理解了方法参数与返回值,各个增删改查方法都是大同小异,都是各种重载方法。
@Param(Constants.WRAPPER) Wrapper queryWrapper
FieldStrategy常量 | 描述 |
---|---|
IGNORED | 忽略判断,不建议使用,如果属性值为null,只会用=比较,不会用is,查询结果不对 |
NEVER | 从不作为条件 |
NOT_NULL | 非NULL判断,默认值 |
NOT_EMPTY | 非空判断(只对字符串类型字段,其他类型字段依然为非NULL判断) |
DEFAULT | 追随全局配置 |
SqlCondition常量 | 描述 |
---|---|
EQUAL | 等于column=value,默认值 |
NOT_EQUAL | 不等于column<>value |
LIKE | 左右模糊查询,column like ‘%value%’ |
LIKE_LEFT | 左模糊查询,column like ‘%value’ |
LIKE_RIGHT | 右模糊查询,column like ‘value%’ |
实体属性注解设置
// condition = SqlCondition.LIKE 字符串模糊查询
// whereStrategy=FieldStrategy.NOT_EMPTY 字符串为null或""则不会作为条件,注意空格会作为条件
@TableField(condition = SqlCondition.LIKE, whereStrategy=FieldStrategy.NOT_EMPTY)
private String bookName;
Wrapper参数测试
//构造条件实体对象
Book book = new Book();
book.setCategoryId(4); //非null属性作等值比较 category_id=4
book.setBookPrice(null); //默认情况下null值属性不会作为默认值
book.setBookName("书籍"); //bookName属性上设置了SqlCondition.LIKE,所以不再是等值比较,而是like
//创建Wrapper,并把实体对象传递构造函数中
QueryWrapper<Book> wrapper = new QueryWrapper<>(book);
//SELECT * FROM book WHERE book_name LIKE CONCAT('%',?,'%') AND category_id=?
List<Book> bookList = bookService.list(wrapper);
bookList.forEach(System.out::println);
//SELECT * FROM book WHERE category_id=?
System.out.println("==========================空字符串============================");
book.setBookName(""); //bookName属性上设置了FieldStrategy.NOT_EMPTY,null值与空字符串都不会作为条件
bookList = bookService.list(wrapper);
bookList.forEach(System.out::println);
//SELECT * FROM book WHERE book_name LIKE CONCAT('%',?,'%') AND category_id=?
System.out.println("=============================空格=========================");
book.setBookName(" "); //bookName属性即使设置了FieldStrategy.NOT_EMPTY,空格也会作为条件
bookList = bookService.list(wrapper);
bookList.forEach(System.out::println);
//SELECT * FROM book
System.out.println("=======================Wrapper为null======================");
bookList = bookService.list(null); //Wrapper为null则不添加条件
bookList.forEach(System.out::println);
@Param(Constants.COLUMN_MAP) Map columnMap
//构造Map条件
Map<String,Object> map=new HashMap<>();
map.put("category_id",4); //key值必须是列名,否则会报错 category_id=4
map.put("book_name",null); // value为null也会作为条件, book_name is null
//SELECT * FROM book WHERE category_id = ? AND book_name IS NULL
List<Book> list = bookMapper.selectByMap(map);
@Param(Constants.COLLECTION) Collection extends Serializable> idList
//构建主键集合
List<Integer> idList = Arrays.asList(1, 3, 6);
//SELECT FROM book WHERE book_id IN ( ? , ? , ? )
List<Book> bookList = bookMapper.selectBatchIds(idList);
bookList.forEach(System.out::println);
IPage page
//构建Page分页对象,第一参数是当前页码,第二参数是每页显示的记录数,
//第三参数是否执行count语句,默认为true,如果只查询数据可以把参数设为false
Page page=new Page(1,2,true);
//SELECT * FROM book LIMIT ?,?
Page<Book> bookPage = bookMapper.selectPage(page,null);
Function super Object, V> mapper
(可直接忽略,几乎不用)
//必须有返回值,obj是主键值,Object类型,如需根据主键值删改查,需要强制转换为Serializable
Function function= obj->{
if(obj!=null) {
//获取主键值
Serializable id = (Serializable) obj;
/* 此处可以根据主键值id进行一系列的额外操作 */
// xxxService.getById(id);
// xxxService.deleteById(id);
// xxxService.updateById(id);
//返回值可以根据实际返回任何数据
return id;
}
return null;
};
//SELECT * FROM book
//Function的返回值类型V,而listObjs返回值类型List,因为结果集有多行记录
// List listObjs(Wrapper queryWrapper, Function super Object, V> mapper);
List<Serializable> list = bookService.listObjs(null, function);
int
boolean
List
List
Collection
IPage
//构建Page分页对象
Page page=new Page(1,2);
//SELECT * FROM book LIMIT ?,?
Page<Book> bookPage = bookMapper.selectPage(page,null);
//bookPage与page是一样的
System.out.println(page==bookPage); //输出true
List<Book> bookList = bookPage.getRecords(); //当前分页查询返回的记录
long totalRows=bookPage.getTotal(); //总记录数
long totalPage=bookPage.getPages(); //总页数
方法说明
// 根据主键查询单条记录
T selectById(Serializable id);
// 根据 Wrapper 条件,查询一条记录返回单个实体对象
T selectOne(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
// 根据主键集合查询多条记录返回对象集合
List<T> selectBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);
// 根据 Wrapper 条件,查询多条记录返回对象集合
List<T> selectList(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
// 根据 columnMap 条件,查询多条记录返回对象集合
List<T> selectByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);
// 根据 Wrapper 条件,查询多条记录返回Map集合,每行记录为Map,列名为key,列值为value
List<Map<String, Object>> selectMaps(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
// 根据 Wrapper 条件,查询多条记录。注意: 只返回第一个列的值
List<Object> selectObjs(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
// 条件分页查询,返回对象集合类型的IPage
IPage<T> selectPage(IPage<T> page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
// 条件分页查询,返回Map类型的IPage
IPage<Map<String, Object>> selectMapsPage(IPage<T> page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
// 根据 Wrapper 条件,查询总记录数
Integer selectCount(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
测试例子
//根据Wrapper条件查询所有记录,返回对象集合
//SELECT * FROM book
//这里Wrapper参数为null,则不会添加条件
List<Book> bookList = bookMapper.selectList(null);
//根据Wrapper条件查询返回单条记录
//SELECT * FROM book WHERE book_id=?
Book book=new Book();
book.setBookId(1);
book.setBookName(null); //null值的属性不会作为条件
Book book2 = bookMapper.selectOne(new QueryWrapper<>(book));
//根据Map条件查询并返回对象集合
//SELECT * FROM book WHERE category_id = ? AND book_date IS NULL
Map<String,Object> conditionMap=new HashMap<String,Object>();
//这里的key要用数据库表Book的列名,而不是用Book实体类的categoryId丶bookDate
conditionMap.put("category_id",1);
conditionMap.put("book_date",null);
List<Book> bookList = bookMapper.selectByMap(conditionMap);
bookList.forEach(System.out::println);
//根据Wrapper条件查询所有记录,并返回Map集合
//SELECT * FROM book
List<Map<String, Object>> mapList = bookMapper.selectMaps(null);
//遍历每行记录
for (Map<String,Object> map : mapList) {
//遍历每列
for (String key : map.keySet()) {
System.out.println("key:"+key+",value:"+map.get(key));
}
}
方法说明
// 插入一条记录,返回受影响的行数(>0表示插入成功),方法执行完后会自动把主键值赋值到实体的主键属性上,null值属性不会插入到数据库
int insert(T entity);
测试例子
//INSERT INTO book ( book_name, book_price ) VALUES ( ?, ? )
Book book=new Book();
book.setBookName("书籍03");
book.setBookPrice(BigDecimal.valueOf(10.3));
book.setBookDate(null); //null值属性不会插入到数据库
int result= bookMapper.insert(book);
if(result>0){
System.out.println("插入成功");
System.out.println(book); //插入成功后book对象有主键值
}else{
System.out.println("插入失败");
}
方法说明
// 根据 Wrapper条件,更新记录,返回受影响的行数,null属性不会更新到数据库
int update(@Param(Constants.ENTITY) T entity, @Param(Constants.WRAPPER) Wrapper<T> updateWrapper);
// 根据实体的主键值更新记录,返回受影响的行数,null属性不会更新到数据库
int updateById(@Param(Constants.ENTITY) T entity);
测试例子
//根据Wrapper条件更新记录
//UPDATE book SET book_price=? WHERE category_id=?
//需要更新的实体类
Book book=new Book();
//把书籍价格都设置为100
book.setBookPrice(BigDecimal.valueOf(100));
book.setBookDate(null); //null值属性不会更新到数据库
//条件实体类
Book conditionBook=new Book();
conditionBook.setCategoryId(4);
conditionBook.setBookName(null); //null值属性不会作为条件
int result= bookMapper.update(book,new UpdateWrapper<>(conditionBook));
//根据实体主键值更新记录
//UPDATE book SET book_name=? WHERE book_id=?
//需要更新的实体类
Book book=new Book();
book.setBookId(10); //设置主键值
book.setBookName("修改后的书籍名");
book.setBookDate(null); //null值属性不会更新到数据库
int result= bookMapper.updateById(book);
方法说明
// 根据 Wrapper条件,删除记录,返回受影响的行数
int delete(@Param(Constants.WRAPPER) Wrapper<T> wrapper);
// 删除主键集合批量删除记录,返回受影响的行数
int deleteBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);
// 根据主键值删除单条记录,返回受影响的行数
int deleteById(Serializable id);
// 根据 columnMap 条件,删除记录,返回受影响的行数
int deleteByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);
测试例子
//根据主键值集合删除多条记录
//DELETE FROM book WHERE book_id IN ( ? , ? )
//设置主键值集合
List<Serializable> ids=new ArrayList<>();
ids.add(14);
ids.add(15);
int result=bookMapper.deleteBatchIds(ids);
//根据Wrapper条件删除多条记录
//DELETE FROM book WHERE book_name=? AND category_id=?
Book book=new Book();
book.setCategoryId(6);
book.setBookName("书籍02");
book.setBookDate(null); //null属性不会作为条件
int result=bookMapper.delete(new QueryWrapper<>(book));
方法说明
// 根据主键查询单条记录
T getById(Serializable id);
// 根据 Wrapper,查询单条记录,如果结果集返回多条记录,则会抛出异常
T getOne(Wrapper<T> queryWrapper);
// 根据 Wrapper,查询单条记录; 如果结果集返回多条记录,throwEx参数值为
// true,则抛出异常,throwEx为false,则返回结果集中的第一条记录
T getOne(Wrapper<T> queryWrapper, boolean throwEx);
// 根据 Wrapper,查询单条记录,返回Map集合,列名为key,列值为value
Map<String, Object> getMap(Wrapper<T> queryWrapper);
// 根据 Wrapper,查询一条记录
<V> V getObj(Wrapper<T> queryWrapper, Function<? super Object, V> mapper);
测试例子
// SELECT * FROM book WHERE category_id=?
Book book=new Book();
book.setCategoryId(4);
//该结果集返回了多条记录,throwEx为false,所以不会抛出异常,会把结果集中的第一条数据返回
Book b = bookService.getOne(new QueryWrapper<>(book),false);
方法说明
// 查询所有
List<T> list();
// 根据Wrapper条件查询多条记录
List<T> list(Wrapper<T> queryWrapper);
// 根据主键值集合查询多条记录
Collection<T> listByIds(Collection<? extends Serializable> idList);
// 根据 columnMap 条件查询多条记录
Collection<T> listByMap(Map<String, Object> columnMap);
// 查询所有记录,返回List
List<Map<String, Object>> listMaps();
// 根据Wrapper条件查询多条记录,返回List
List<Map<String, Object>> listMaps(Wrapper<T> queryWrapper);
// 查询所有记录,只返回第一列的数据
List<Object> listObjs();
// 对所有查询结果进行额外的操作(可忽略)
<V> List<V> listObjs(Function<? super Object, V> mapper);
// 根据 Wrapper 条件,查询所有记录,值返回第一列的数据
List<Object> listObjs(Wrapper<T> queryWrapper);
// 根据 Wrapper 条件查询多条记录,对查询结果进行额外的操作(可忽略)
<V> List<V> listObjs(Wrapper<T> queryWrapper, Function<? super Object, V> mapper);
方法说明
// 查询总记录数
int count();
// 根据 Wrapper 条件,查询总记录数
int count(Wrapper<T> queryWrapper);
方法说明
// 插入一条记录
boolean save(T entity);
// 批量插入多条记录,每插入一条记录执行一次insert语句
boolean saveBatch(Collection<T> entityList);
// 批量插入多条记录,每隔batchSize条记录执行一次insert语句(性能稍高)
boolean saveBatch(Collection<T> entityList, int batchSize);
测试例子
//创建5个Book对象放进List集合中
List<Book> bookList=new ArrayList<>();
for (int i = 1; i <=5 ; i++) {
Book book=new Book();
book.setBookName("书籍"+i);
bookList.add(book);
}
// insert语句执行次数=向上取整(bookList元素数量/batchSize)
bookService.saveBatch(bookList, 3);
方法说明
// 以updateWrapper作为update语句的where条件
// 该方法必须updateWrapper调用set()来设置需要更新的列和值
boolean update(Wrapper<T> updateWrapper);
// 以updateWrapper作为update语句的where条件
// 以entity作为需要更新的列和值,默认情况下null值属性不会被更新
boolean update(T entity, Wrapper<T> updateWrapper);
// 以主键作为update语句的where条件
// 以entity作为需要更新的列和值,默认情况下null值属性不会被更新
// 主键必须有值,如果值为null,条件会变成book_id=null
boolean updateById(T entity);
// 根据实体集合的主键值批量更新,每隔1条记录执行一次update语句
boolean updateBatchById(Collection<T> entityList);
// 根据实体集合的主键值批量更新,每隔batchSize条记录执行一次update语句(性能稍高)
boolean updateBatchById(Collection<T> entityList, int batchSize);
测试例子
/*** 以主键为条件,以实体对象作为更新的列和值 ***/
Book book=new Book();
book.setBookId(41); //主键必须有值,如果值为null,条件会变成book_id=null
book.setBookPrice(BigDecimal.valueOf(60));
book.setBookDate(LocalDateTime.now());
// UPDATE book SET book_date=?, book_price=? WHERE book_id=?
bookService.updateById(book);
/*** 以updateWrapper为条件,自定义set需要更新的列和值 ***/
// 构建update语句的where条件
Book conditionBook=new Book();
conditionBook.setCategoryId(7);
UpdateWrapper<Book> updateWrapper=new UpdateWrapper(conditionBook);
// 必须设置更新的列和值,即update语句的set关键字后面那部分
updateWrapper.set("book_price",50);
updateWrapper.set("book_date", LocalDateTime.now());
// UPDATE book SET book_price=?,book_date=? WHERE category_id=?
bookService.update(updateWrapper);
/*** 以updateWrapper为条件,以实体对象作为更新的列和值 ***/
// 构建update语句的where条件
Book conditionBook=new Book();
conditionBook.setCategoryId(7);
UpdateWrapper<Book> updateWrapper=new UpdateWrapper(conditionBook);
// 构建update语句的set后面部分
Book book=new Book();
book.setBookPrice(BigDecimal.valueOf(60));
book.setBookDate(LocalDateTime.now());
// UPDATE book SET book_price=?,book_date=? WHERE category_id=?
bookService.update(book,updateWrapper);
方法说明
// 如果实体主键不为null,则进行更新操作
// 如果实体主键为null,则进行新增操作
// 更新与新增的方法说明请查看3.4与3.5
boolean saveOrUpdate(T entity);
boolean saveOrUpdate(T entity, Wrapper<T> updateWrapper);
boolean saveOrUpdateBatch(Collection<T> entityList);
boolean saveOrUpdateBatch(Collection<T> entityList, int batchSize);
测试例子
Book book=new Book();
book.setBookId(41); //主键值不为null执行修改更新操作
book.setBookPrice(BigDecimal.valueOf(80));
book.setBookDate(LocalDateTime.now());
// SELECT * FROM book WHERE book_id=? //比update方法多了一个查询语句 ?????
// UPDATE book SET book_date=?, book_price=? WHERE book_id=?
bookService.saveOrUpdate(book);
book.setBookId(null); //主键值为null执行插入新增操作
// INSERT INTO book ( book_date, book_price ) VALUES ( ?, ? )
bookService.saveOrUpdate(book);
System.out.println(book);
方法说明
// 根据queryWrapper条件删除多条记录
boolean remove(Wrapper<T> queryWrapper);
// 根据主键值删除单条记录
boolean removeById(Serializable id);
// 根据 columnMap 条件删除多条记录
boolean removeByMap(Map<String, Object> columnMap);
// 根据主键集合删除多条记录
boolean removeByIds(Collection<? extends Serializable> idList);
package com.config;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.extension.plugins.pagination.optimize.JsqlParserCountOptimize;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;
//Spring boot方式
@EnableTransactionManagement
@Configuration
public class MybatisPlusConfig {
@Bean
public PaginationInterceptor paginationInterceptor() {
PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
// 设置请求的页面大于最大页后操作, true调回到首页,false 继续请求 默认false
// paginationInterceptor.setOverflow(false);
// 设置最大单页限制数量,默认 500 条,-1 不受限制
// paginationInterceptor.setLimit(500);
// 开启 count 的 join 优化,只针对部分 left join
paginationInterceptor.setCountSqlParser(new JsqlParserCountOptimize(true));
return paginationInterceptor;
}
}
方法说明
// 无条件分页查询,返回Page对象,封装的数据是List类型
IPage<T> page(IPage<T> page);
// 条件分页查询,返回Page对象,封装的数据是List类型
IPage<T> page(IPage<T> page, Wrapper<T> queryWrapper);
// 无条件分页查询,返回Page对象,封装的数据是List
IPage<Map<String, Object>> pageMaps(IPage<T> page);
// 条件分页查询,返回Page对象,封装的数据是List
IPage<Map<String, Object>> pageMaps(IPage<T> page, Wrapper<T> queryWrapper);
测试例子
//构建Page分页对象,第一参数是当前页码,第二参数是每页显示的记录数,第三参数是否执行count语句,默认为true
Page page=new Page(1,2);
// SELECT COUNT(1) FROM book //Page构造函数的第三个参数指定是否执行该语句
// SELECT * FROM book LIMIT ?,?
Page<Book> bookPage = bookService.page(page);
//bookPage与page是一样的
System.out.println(page==bookPage); //输出true
List<Book> bookList = bookPage.getRecords(); //当前分页查询返回的记录
//执行了count语句,总记录数和总页数才能正确计算,否则值都为0
long totalRows=bookPage.getTotal(); //总记录数
long totalPage=bookPage.getPages(); //总页数
System.out.println(totalRows);
System.out.println(totalPage);
bookList.forEach(System.out::println);
public interface BookMapper extends BaseMapper<Book> {
// 普通的查询语句
@Select("select * from book where book_name like #{bookName} and category_id=#{categoryId}")
// IPage method(Page> page,sql语句参数...) 把普通查询变成分页查询
IPage<Book> findByPage(Page<?> page, String bookName,Integer categoryId);
}
//测试自定义分页
Page page=new Page(2,3);
bookMapper.findByPage(page,"%书籍%",4);
System.out.println(page.getTotal());
System.out.println(page.getPages());
page.getRecords().forEach(System.out::println);
链式方法:Service实现类可以直接调用条件构造器的方法进行条件拼接,最后再调用特定的改查方法
方法说明
// 下面4个类都可以调用条件构造器的方法
// Lambda开头的类支持Lambda表达式构造条件,避免列名与实体属性名不一致的问题
// 链式查询 普通
QueryChainWrapper<T> query();
// 链式查询 lambda 式。注意:不支持 Kotlin
LambdaQueryChainWrapper<T> lambdaQuery();
// 链式更改 普通
UpdateChainWrapper<T> update();
// 链式更改 lambda 式。注意:不支持 Kotlin
LambdaUpdateChainWrapper<T> lambdaUpdate();
//QueryChainWrapper类与LambdaQueryChainWrapper特有方法
List<T> list() //查询多条记录
T One() //查询单条记录,如果查询结果有多条记录,则会报错
//UpdateChainWrapper与LambdaUpdateChainWrapper特有方法
boolean update() //修改记录,必须设置set后面的语句
boolean update(T t) //修改记录,以实体对象的非null属性作为需要修改的列和值
测试例子
// Service实现类转换成QueryChainWrapper
// 调用了条件构造器方法拼接查询条件 category_id=4 and book_price<200
// 最后调用QueryChainWrapper特有方法list()查询多条记录
// SELECT * FROM book WHERE (category_id = ? AND book_price < ?)
List<Book> bookList = bookService.query().eq("category_id", 4).lt("book_price", 200).list();
// Service实现类转换成LambdaQueryChainWrapper
// 调用了条件构造器方法拼接查询条件 book_id=1
// 最后调用LambdaQueryChainWrapper特有方法one()查询单条记录
// SELECT * FROM book WHERE (book_id = ?)
Book b = bookService.lambdaQuery().eq(Book::getBookId, 1).one();
// Service实现类转换成UpdateChainWrapper
// 调用了条件构造器方法拼接修改条件 book_id=40
// 最后调用UpdateChainWrapper特有方法update()修改记录
// 因为update()方法是无参的,所以必须通过set()设置要修改的列和值 set book_price=500
// UPDATE book SET book_price=? WHERE (book_id = ?)
bookService.update().set("book_price",500).eq("book_id",40).update();
// Service实现类转换成LambdaUpdateChainWrapper
// 调用了条件构造器方法拼接修改条件 book_id=40
// 最后调用LambdaUpdateChainWrapper特有方法update(entity)修改记录
// 因为update(entity)传递了实体对象,所以直接根据entity的非null属性作为更新的列和值,不用再额外调用set()方法
// UPDATE book SET book_price=? WHERE (book_id = ?)
Book book=new Book();
book.setBookPrice(BigDecimal.valueOf(500));
bookService.lambdaUpdate().eq(Book::getBookId,40).update(book);
主要作用是拼接where条件,其次作用是设置sql语句中与列相关的部分
多个Entity属性条件 and (多个Wrapper方法条件)
,两种条件是相互独立的//实体对象设置2个条件 book_name like '%书籍%' and book_price=100
Book book=new Book();
book.setBookName("书籍"); //因为实体类上用了注解,所以这里是模糊查询
book.setBookPrice(BigDecimal.valueOf(100));
QueryWrapper<Book> queryWrapper=new QueryWrapper<>(book);
//Wrapper设置两个条件 category_id=4 or category_id=7
queryWrapper.eq("category_id",4).or().eq("category_id",7);
//SELECT * FROM book WHERE book_name LIKE CONCAT('%',?,'%') AND book_price=? AND (category_id = ? OR category_id = ?)
List<Book> bookList = bookService.list(queryWrapper);
//Wrapper条件的小括号()保证了查询结果的准确性
bookList.forEach(System.out::println);
.eq("book_price",100)
Lambda方式 .eq(Book::getBookPrice,100)
子类:QueryWrapper、LambdaQueryWrapper、QueryChainWrapper、LambdaQueryChainWrapper、UpdateWrapper、LambdaUpdateWrapper、UpdateChainWrapper、LambdaUpdateChainWrapper
通用参数说明
boolean condition
R column
Object val
Consumer consumer
方法说明
eq(R column, Object val) //相等 =
ne(R column, Object val) //不等 <>
gt(R column, Object val) //大于 >
ge(R column, Object val) //大于等于 >=
lt(R column, Object val) //小于 <
le(R column, Object val) // 小于等于
/* 多个条件进行等值比较,null值用value is null作为条件,用and连接每个条件 */
allEq(Map<R, V> params)
allEq(Map<R, V> params, boolean null2IsNull)
参数说明:
Map
Map的key为params R column
,value为Object val
boolean null2IsNull
null值是否作为条件,默认为true,条件为val is null
;如果为false,则忽略列值为null的条件
//构造多个条件
Map<String, Object> map = new HashMap<>();
map.put("category_id", 4);
map.put("book_name",null);
QueryWrapper<Book> queryWrapper = new QueryWrapper<>();
queryWrapper.allEq(map); //多个条件比较
// SELECT * FROM book WHERE (category_id = ? AND book_name IS NULL)
List<Book> bookList = bookService.list(queryWrapper);
//column between val1 and val2
between(R column, Object val1, Object val2)
//column not between val1 and val2
notBetween(R column, Object val1, Object val2)
like(R column, Object val) // column like '%val%'
notLike(R column, Object val) // column not like '%val%'
likeLeft(R column, Object val) // column like '%val'
likeRight(R column, Object val) // column like 'val%'
isNull(R column) // column is null
isNotNull(R column) // column is not null
in(R column, Collection<?> value) //column in (value1,value2,...)
notIn(R column, Collection<?> value) //column not in (value1,value2,...)
inSql(R column, String inSql) // column in (自定义sql片段)
notInSql(R column, String inSql) //column not in (自定义sql片段)
参数说明:
Collection> value
多个比较条件值,每个值放进集合中
inSql
sql语句中比较条件in关键字后添加自定义的sql片段(注意防注入)
// category_id IN (1,2,3,4)
wrapper.in("category_id", Arrays.asList(1,2,3,4));
//category_id in (select category_id from book where book_price>100)
wrapper.inSql("category_id","select category_id from book where book_price>100");
exists(String existsSql)
notExists(String existsSql)
参数说明:
existsSql
exists关键字后面的sql片段,注意防注入
//SELECT * FROM book WHERE (EXISTS (select book_id from book where book_name='西游记'))
wrapper.exists("select book_id from book where book_name='西游记'");
groupBy(R... columns) // group by column1,column2,...
having(String sqlHaving, Object... params)
参数说明:
sqlHaving
having关键字后面的sql片段,可用下标占位符,从0开始
params
having条件sql语句中的占位符实际参数值
QueryWrapper<Book> wrapper=new QueryWrapper();
wrapper.select("category_id");
wrapper.groupBy("category_id");
wrapper.having("count(*)>{0} and count(*)<{1}",3,7);
// SELECT category_id FROM book GROUP BY category_id HAVING count(*)>3 and count(*)<7
List list = bookService.listObjs(wrapper);
list.forEach(System.out::println);
orderByAsc(R... columns) // order by column1 asc,column2 asc,... asc
orderByDesc(R... columns) // order by column1 desc,column2 desc,... desc
orderBy(boolean condition, boolean isAsc, R... columns) //不要用,麻烦
//主动调用or()表示【紧接着下一个方法】条件用or连接,否则用and连接
or()
// or嵌套
//or(w-> w.eq("name", "李白").ne("status", "活着"))--->or (name = '李白' and status <> '活着')
or(Consumer<Param> consumer)
// or()只对紧邻下一个方法的拼接条件有效
// category_id = 1 OR category_id = 4 AND book_price > 50 AND book_price < 150
wrapper.eq("category_id",1).or().eq("category_id",4).gt("book_price",50).lt("book_price",150);
//调用带Consumer方法参数的方法时,必须声明Wrapper时必须指定实际泛型,否则直接爆红编译错误
QueryWrapper<Book> wrapper=new QueryWrapper();
wrapper.gt("category_id",1);
//w就是QueryWrapper对象wrapper,or方法里面的条件最终会被小括号()包住
wrapper.or(w -> w.gt("book_price",50).lt("book_price",200));
wrapper.lt("category_id",1);
// SELECT * FROM book WHERE (category_id > ? OR (book_price > ? AND book_price < ?) AND category_id < ?)
List<Book> bookList = bookService.list(wrapper);
bookList.forEach(System.out::println);
// and嵌套,具体用法看or
//and(w-> w.eq("name", "李白").ne("status", "活着"))--->and (name = '李白' and status <> '活着')
and(Consumer<Param> consumer)
// 不带连接关键字的嵌套,具体用法看or
//nested(w-> w.eq("name", "李白").ne("status", "活着"))--->(name = '李白' and status <> '活着')
nested(Consumer<Param> consumer)
//无视优化规则直接拼接到 sql 的最后
//只能调用一次,多次调用以最后一次为准 有sql注入的风险,请谨慎使用
last(String lastSql)
// 自定义sql条件,可以用下标占位符(从0开始)防止sql注入
apply(String applySql, Object... params)
//book_price>50 and book_price<100
wrapper.apply("book_price>{0} and book_price<{1}",50,100);
select(String... sqlSelect) //查询包含指定列
select(Predicate<TableFieldInfo> predicate) //根据实体属性筛选查询列
select(Class<T> entityClass, Predicate<TableFieldInfo> predicate) //根据实体属性筛选查询列
lambda() // QueryWrapper转换为LambdaQueryWrapper
参数说明:
Predicate
Lambda表达式,传递的参数是实体属性TableFieldInfo,Lambda返回值为true则表示该属性会作为查询列predicate
// 1个方法参数可以指定多列,多个参数最终会以逗号合并
// SELECT book_name,book_price,book_date FROM book
wrapper.select("book_name,book_price","book_date");
// 调用带参数Predicate必须声明Wrapper的实参泛型
QueryWrapper<Book> wrapper=new QueryWrapper();
// f就是QueryWrapper对象,该Lambda表达式必须返回布尔类型
// 因为Wrapper没有添加实体类对象,所以必须添加第一个方法参数Class entityClass
// Lambda表达式筛选列是根据实体类的属性名或列名进行筛选的,主键属性无法过滤
// f.getProperty()获取的是属性名,f.getColumn()获取的是列名
// SELECT book_id,book_name FROM book
wrapper.select(Book.class,f->f.getProperty().contains("bookName"));
Book book=new Book();
book.setCategoryId(4);
// 调用带参数Predicate必须声明Wrapper的实参泛型
// 这里把book实体对象放进了Wrapper中
QueryWrapper<Book> wrapper=new QueryWrapper(book);
// f就是QueryWrapper对象,该Lambda表达式必须返回布尔类型
// 因为Wrapper添加实体类对象,所以不用再设置Class entityClass参数
// Lambda表达式筛选列是根据实体类的属性名或列名进行筛选的,主键属性无法过滤
// f.getProperty()获取的是属性名,f.getColumn()获取的是列名
// SELECT book_id,book_name FROM book WHERE category_id=?
wrapper.select(f->f.getProperty().contains("bookName"));
set(String column, Object val) // 设置要修改的列和值
setSql(String sql) // 设置更新sql语句中的set关键字的sql片段,注意防注入
lambda() // UpdateWrapper转换为LambdaUpdateWrapper
UpdateWrapper<Book> updateWrapper=new UpdateWrapper<>();
updateWrapper.set("book_name","UpdateWrapper书籍").set("category_id",8);
updateWrapper.eq("book_id",36);
//UPDATE book SET book_name=?,category_id=? WHERE (book_id = ?)
bookService.update(updateWrapper);
QueryChainWrapper qcWrapper=xxxService.query();
LambdaQueryChainWrapper lqcWrapper=xxxService.lambdaQuery();
T one() //查询返回一条记录
List<T> list() //查询返回多条记录
Integer count() //查询记录数
E page(E page) //分页查询
// SELECT * FROM book WHERE (category_id = ?)
List<Book> bookList = bookService.query().eq("category_id",4).list();
Page<Book> page=new Page(1,2); //分页对象
// SELECT COUNT(1) FROM book WHERE (book_price > ? AND book_price < ?)
// SELECT * FROM book WHERE (book_price > ? AND book_price < ?) LIMIT ?,?
bookService.lambdaQuery().gt(Book::getBookPrice,50).lt(Book::getBookPrice,150).page(page);
long total = page.getTotal(); //总记录数
long pages = page.getPages(); //总页数
List<Book> bookList = page.getRecords(); //条件分页后的查询结果
UpdateChainWrapper ucWrapper=xxxService.update();
LambdaUpdateChainWrapper lucWrapper=xxxService.lambdaUpdate();
boolean update() // 以条件构造器为条件,必须调用set()方法设置需要修改的列
boolean update(T entity) // 以条件构造器为条件,以entity的非null属性作为需要更新的列
boolean remove() // 以条件构造器为条件,删除多条记录
// 第一个update()方法是获取UpdateChainWrapper,第二个update()是执行update语句
// 因为最后的update()没有指定实体对象,所以必须调用set()方法设置需要修改列和值
// UPDATE book SET book_name=? WHERE (book_id = ?)
bookService.update().set("book_name","书籍36已修改").eq("book_id",36).update();
// 使用实体对象指定需要修改列和值
Book book=new Book();
book.setBookName("书籍36Lambda修改");
// UPDATE book SET book_name=? WHERE (book_id = ?)
bookService.lambdaUpdate().eq(Book::getBookId,36).update(book);