Bootstrap

mybatis-plus之条件构造器

AbastractWrapper是一个抽象类,他继承自Wrapper的抽象类,就update和query来说,子类实现有四个,他们也分别实现了一些接口

AbstractWrapper包括以下方法,这里只挑一些说明,具体看文档

allEq(map里面的条件用and链接)

allEq(boolean condition, BiPredicate<R, V> filter, Map<R, V> params, boolean null2IsNull) 

filter:声明可以接受两个参数的并且返回boolean类型函数式,过滤函数,是否允许字段传入比对条件中,可以用来判断传入字段是否合法

params:key为数据库字段名,value为字段值

null2IsNull:true则在map的value为null时调用isNull方法(即该字段的条件为 is null),为false则不做添加条件

condition:该条件是否加入最后生成的sql中

        wrapper.select("name","id","age").between("age",20,31).nested(i->i.eq("name","lele")).or().like(false,"email","@qq");
//SELECT name,id,age FROM user WHERE age BETWEEN ? AND ? AND ( name = ? ) 
//这里的like因为condition设置为false没有加进去

eq(等同于=)

eq(R column, Object val)

ne(不等于<>)

ne(R column, Object val)

gt(大于>)

gt(R column, Object val)

lt(小于<)

lt(R column, Object val)

ge(大于等于>=)

ge(R column, Object val)

le(小于等于)

le(R column, Object val)

between(区间 between and)

between(R column, Object val1, Object val2)

notBetween(not between and)

notBetween(R column, Object val1, Object val2)

like(%值%)

like(R column, Object val)

notLike(not like %值%)

notLike(boolean condition, R column, Object val)

likeLeft(%值,以什么开头)

likeLeft(boolean condition, R column, Object val)

likeRight(值%,以什么结尾)

likeRight(boolean condition, R column, Object val)

isNotNull(字段 is not null)

isNotNull(boolean condition, R column)

in(字段范围in)

notIn(boolean condition, R column, Collection<?> value)

notIn(字段范围 not in)

notIn(boolean condition, R column, Object... values)

inSql(子查询 in)

inSql(boolean condition, R column, String inValue)

notInSql(子查询 not in)

notInSql(boolean condition, R column, String inValue)

groupBy(这个使用时候有个小插曲)

groupBy(R... columns)
        wrapper.select("age").groupBy("age");
        userDao.selectObjs(wrapper).forEach(System.out::println);

这里的结果是查询出一列的,假如多列的话,比如下面这个例子,查出来也是一列。

 wrapper.select("age,count(*)").groupBy("age");

但是分组统计的数据另建一个实体又比较麻烦,我一开始是想把所查数据拼接起来的比如下面这个例子

        wrapper.select("CONCAT_WS('-',age,COUNT(*))").groupBy("age");

却返回这种结果

然后上网找到原因,原来要进行输出编码的控制,最终语句如下,然后再用-分隔字符串取出所要的数据

        wrapper.select("CONVERT(CONCAT_WS('-',age,COUNT(*)) USING utf8)").groupBy("age");

当然其实更简单的是把接受的参数改为map,即userDao.selectMap(后来才发现有这个方法。。。)

orderByAsc(降序)

orderByAsc(R... columns)

orderByDesc(升序)

orderByDesc(boolean condition, R... columns)

orderBy(多字段同排序条件)

orderBy(boolean condition, boolean isAsc, R... columns)
        wrapper.orderBy(true,false,"age","name");
//ORDER BY age DESC , name DESC 

having

having(boolean condition, String sqlHaving, Object... params)

or(拼接的or,因为默认是and拼接)

or()

or(用法同and)

or(boolean condition, Function<Param, Param> func)

and(括号前面有and,括号里面是语句)

and(boolean condition, Function<Param, Param> func)

nested(嵌套函数,括号里面的语句,括号前面没有and或者or)

        wrapper.select("name","id","age").between("age",20,31).nested(i->i.eq("name","lele")).or().like("email","@qq");

//SELECT name,id,age FROM user WHERE age BETWEEN ? AND ? AND ( name = ? ) OR email LIKE ?
//括号里面就是nested的语句
nested(Function<Param, Param> func)

apply(拼接sql,最好用占位符形式)

apply(String applySql, Object... params)

last(拼接在sql最后)

last(String lastSql)
wrapper.apply("name like {0} and age > {1}","%l%",19).last("limit 2");
//SELECT id,name,age,email FROM user WHERE name like ? and age > ? limit 2 

exists(拼接sql语句 exists),判断where前面的每行数据是否满足exists的条件,如果满足则返回

exists(String existsSql)
wrapper.exists("SELECT * FROM USER u WHERE u.age < 30 AND user.`age`=u.`age`");

notExists(拼接sql语句 not exists) 判断where前面的每行数据是否满足not exists的条件,如果不满足则返回

notExists(String notExistsSql)
wrapper.notExists("SELECT * FROM USER u WHERE EXISTS( SELECT *  FROM USER  uu WHERE uu.age < 30 AND u.age=uu.`age` AND u.age=user.age)");
/**SELECT id,name,age,email FROM user WHERE NOT EXISTS (SELECT * FROM USER u WHERE EXISTS( SELECT * FROM USER uu WHERE uu.age < 30 AND u.age=uu.`age` AND u.age=user.age))
*这句话的意思是找出不满足(满足年龄小于30),其实就是找年龄>=30的人
*/

构建wrapper用了builder模式,使得整个对象构造十分灵活,可以根据需求灵活构建查询对象

select(查询的字段)

Predicate是返回boolean类型的函数式,第二个这里主要用来过滤不合法的字段(主键除外),第三个在第二的基础上限定调用的类

select(String... sqlSelect)
select(Predicate<TableFieldInfo> predicate)
select(Class<T> entityClass, Predicate<TableFieldInfo> predicate)

set(update)

set(String column, Object val)
set(boolean condition, String column, Object val)

例子如下,setSql可以更改多列,set就是单列

   UpdateWrapper<User> userUpdateWrapper=new UpdateWrapper<>();
        UpdateWrapper<User> u2=new UpdateWrapper<>();
        userUpdateWrapper.set("age",23).eq("name","lele");//UPDATE user SET age=? WHERE name = ? 
        userDao.update(null,userUpdateWrapper);
        u2.setSql(true,"email='[email protected]',age='100'").eq("name","tjl");// UPDATE user SET email='[email protected]',age='100' WHERE name = ? 
userDao.update(null,u2);

LambdaQueryWrapper这个和上面的一样,只是接受的参数是lambda的函数式

例子如下:

   LambdaQueryWrapper<User> lambdaQueryWrapper=new LambdaQueryWrapper<>();
        LambdaQueryWrapper<User> l1= Wrappers.<User>lambdaQuery();
lambdaQueryWrapper.likeRight(User::getName,"l").lt(User::getAge,30);
//SELECT id,name,age,email FROM user WHERE name LIKE ? AND age < ? 
Map<SFunction<User,?>,Object> map=new HashMap<>();
map.put(User::getAge,23);
map.put(User::getName,"lele");
l1.allEq(map);
//SELECT id,name,age,email FROM user WHERE age = ? AND name = ? 
        userDao.selectList(lambdaQueryWrapper).forEach(System.out::println);
        userDao.selectList(l1).forEach(System.out::println);

LambdaQueryWrapper用法也差不多,这种方式可以保证列名不会出错。

Wrapper可以接受一个实体,默认是=为条件,如

User u=new User();
u.setName("l");
u.setAge(20);
QueryWrapper<User> wrapper=new QueryWrapper(u);
userDao.selectList(wrapper).forEach(System.out::println);

//select  id,name,age,email  from user     where  name=?  and age=?

如果要使用模糊查询、年龄大于等于这种查询怎么办呢?此时可以在属性上的注解做一下手脚,详细配置项,这里我们采用添加condition属性来限制查找的语句

 

使用方式也是如上,最后的sql语句为

select  id,name,age,email  from user     where  name like concat('%',?,'%')  and age>=?

 

;