SpringBoot - MyBatis-Plus使用详解5(Mapper的CRUD接口2:条件构造器)
五、Mapper 的 CRUD 接口2:条件构造器
1,相等、不相等
(1)allEq 表示全部 eq(或个别 isNull):
方法最后一个参数 null2IsNull 是可选的(默认为 true),为 true 时则在 map 的 value 为 null 时调用 isNull 方法,为 false 时则忽略:
- allEq({id:1,user_name:"hangge",age:null}) --- 生成的sql为 ---> id = 1 and user_name = 'hangge' and age is null
- allEq({id:1,user_name:"hangge",age:null}, false) --- 生成的sql为 ---> id = 1 and user_name = 'hangge'
Map<SFunction<UserInfo, ?>, Object> map = new HashMap<>(); map.put(UserInfo::getId, 3); map.put(UserInfo::getUserName, "hangge"); map.put(UserInfo::getAge, null); List<UserInfo> userInfos = new LambdaQueryChainWrapper<>(userInfoMapper) .allEq(map) .list();

(2)eq 表示等于(=),ne 表示不等于(<>)
List<UserInfo> userInfos = new LambdaQueryChainWrapper<>(userInfoMapper) .eq(UserInfo::getId, 1) // id = 1 .ne(UserInfo::getAge, 22) // age <> 22 .list();
2,大于、小于
(1)gt 表示大于(>)、ge 表示大于等于(>=)、lt 表示小于(<)、le 表示小于等于(<=)
List<UserInfo> userInfos = new LambdaQueryChainWrapper<>(userInfoMapper) .gt(UserInfo::getId, 1) // id > 1 .ge(UserInfo::getAge, 22) // age >=18 .lt(UserInfo::getId, 3) // id < 3 .le(UserInfo::getAge, 50) // age <=50 .list();
(2)between 表示(BETWEEN 值1 AND 值2),notBetween 表示(NOT BETWEEN 值1 AND 值2)
List<UserInfo> userInfos = new LambdaQueryChainWrapper<>(userInfoMapper) .between(UserInfo::getId, 1,3) // id between 1 and 3 .notBetween(UserInfo::getAge, 40, 50) // age not between 40 and 50 .list();
3,模糊查询
(1)like 表示包含指定的值(like '%值%'),likeLeft 表示以指定的值结尾(like '%值'),likeRight 表示以指定的值开头(like '值%')
List<UserInfo> userInfos = new LambdaQueryChainWrapper<>(userInfoMapper) .like(UserInfo::getUserName, "ha") // user_name like '%ha%' .likeLeft(UserInfo::getUserName, "ha") // user_name like '%ha' .likeRight(UserInfo::getUserName, "ha") // user_name like 'ha%' .list();
(2)notLike 表示不包含指定的值(not like '%值%')
List<UserInfo> userInfos = new LambdaQueryChainWrapper<>(userInfoMapper) .notLike(UserInfo::getUserName, "ha") // user_name not like '%ha%' .list();
4,是否为 null
isNull 表示字段是否为 null(is null),isNotNull 表示字段是否不为 null(is not null)List<UserInfo> userInfos = new LambdaQueryChainWrapper<>(userInfoMapper) .isNull(UserInfo::getUserName) // user_name is null .isNotNull(UserInfo::getAge) // age is not null .list();
5,in、notIn
List<UserInfo> userInfos = new LambdaQueryChainWrapper<>(userInfoMapper) .in(UserInfo::getId, Arrays.asList(1, 2, 3)) // id in (1,2,3) .notIn(UserInfo::getAge, Arrays.asList(22, 33)) // age not in (22,33) .list();
6,带子查询(sql 注入)
(1)下面是 inSql 的用法:List<UserInfo> userInfos = new LambdaQueryChainWrapper<>(userInfoMapper) .inSql(UserInfo::getAge, "22,33") // age in (22,33) // id in (select id from vip where level > 3) .inSql(UserInfo::getId, "select id from vip where level > 3") .list();
(2)下面是 notInSql 的用法:
List<UserInfo> userInfos = new LambdaQueryChainWrapper<>(userInfoMapper) .notInSql(UserInfo::getAge, "22,33") // age not in (22,33) // id not in (select id from vip where level > 3) .notInSql(UserInfo::getId, "select id from vip where level > 3") .list();
7,排序
orderByAsc 表示升序(ASC),orderByDesc 表示降序(DESC)List<UserInfo> userInfos = new LambdaQueryChainWrapper<>(userInfoMapper) .orderByAsc(UserInfo::getId, UserInfo::getUserName) // ORDER BY id ASC,user_name ASC .orderByDesc(UserInfo::getAge) // ORDER BY age DESC .list();

8,分组、筛选
下面是 groupBy 和 having 的用法:List<UserInfo> userInfos = new LambdaQueryChainWrapper<>(userInfoMapper) .groupBy(UserInfo::getUserName, UserInfo::getAge) // group by user_name,age .having("sum(age) > 20") // HAVING sum(age) > 20 .having("sum(age) > {0}", 30) // HAVING sum(age) > 30 .select(UserInfo::getUserName, UserInfo::getAge) .list();

9,or、 and、nested
(1)主动调用 or 表示紧接着下一个方法是用 or 连接(不调用 or 则默认为使用 and 连接)
// WHERE age = 22 or age = 33 List<UserInfo> userInfos = new LambdaQueryChainWrapper<>(userInfoMapper) .eq(UserInfo::getAge, 22) .or() .eq(UserInfo::getAge, 33) .list();
(2)or、 and、nested 可以实现带嵌套的查询:
- or 为 OR 嵌套
- and 为 AND 嵌套
- nested 为正常嵌套(不带 AND 或者 OR)
// WHERE age IS NOT NULL AND ((id = 1 AND user_name = 'hangge') OR (id = 2 AND user_name = '航歌')) List<UserInfo> userInfos = new LambdaQueryChainWrapper<>(userInfoMapper) .isNotNull(UserInfo::getAge) .and(i -> i.nested( j -> j.eq(UserInfo::getId,1).eq(UserInfo::getUserName,"hangge") ) .or(j -> j.eq(UserInfo::getId,2).eq(UserInfo::getUserName,"航歌")) ) .list();
10,拼接 sql(sql 注入)
(1)apply 方法可以直接将自定义的 sql 拼接到查询条件中:
(2)last 无视优化规则直接拼接到 sql 的最后:
// WHERE age IS NOT NULL AND id = 3 AND user_name = 'hangge' List<UserInfo> userInfos = new LambdaQueryChainWrapper<>(userInfoMapper) .isNotNull(UserInfo::getAge) .apply("id = 3") // 有sql注入的风险 .apply("user_name = {0}", "hangge") //无sql注入的风险 .list();
(2)last 无视优化规则直接拼接到 sql 的最后:
注意:
last 只能调用一次,多次调用以最后一次为准。该方法有 sql 注入的风险,请谨慎使用。
// WHERE age IS NOT NULL limit 2 List<UserInfo> userInfos = new LambdaQueryChainWrapper<>(userInfoMapper) .isNotNull(UserInfo::getAge) .last("limit 2") .list();
11,exists、notExists
(1)exists 方法可以拼接 EXISTS ( sql 语句 ),比如下面查询底下有用户的所有区域:
// SELECT id,area_name FROM area WHERE // (EXISTS (select * from user_info where user_info.area_id = area.id)) List<Area> areas = new LambdaQueryChainWrapper<>(areaMapper) .exists("select * from user_info where user_info.area_id = area.id") .list();
(2)notExists 方法用于拼接 NOT EXISTS ( sql 语句 ),比如下面查询底下没有用户的所有区域:
// SELECT id,area_name FROM area WHERE // (NOT EXISTS (select * from user_info where user_info.area_id = area.id)) List<Area> areas = new LambdaQueryChainWrapper<>(areaMapper) .notExists("select * from user_info where user_info.area_id = area.id") .list();
12,设置查询字段(select)
select 方法可以设置最终查询返回的字段:
List<UserInfo> userInfos = new LambdaQueryChainWrapper<>(userInfoMapper) .select(UserInfo::getUserName, UserInfo::getAge) .list();

附:自定义 SQL 语句使用 Wrapper
mybatis-plus 在 3.0.7 版本之后,也支持自定义 SQL 语句使用 Wrapper,具体有如下两种方案。注意:使用 Wrapper 的话自定义 sql 中不能有 WHERE 语句。
1,注解方式(Mapper.java)
(1)我们可以直接在自定义方法上使用 @Select 设置对应的 sql 语句,然后添加 Wrapper 参数:public interface UserInfoMapper extends BaseMapper<UserInfo> { @Select("SELECT * FROM user_info ${ew.customSqlSegment}") List<UserInfo> getAll(@Param(Constants.WRAPPER) Wrapper wrapper); }
List<UserInfo> userInfos = userInfoMapper.getAll( Wrappers.<UserInfo>lambdaQuery().eq(UserInfo::getId, 1) );
2,XML 形式(Mapper.xml)
(1)首先在 mapper.xml 中添加自定义的 sql 语句:<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.example.demo.mapper.UserInfoMapper"> <select id="getAll" resultType="com.example.demo.model.UserInfo"> SELECT * FROM user_info ${ew.customSqlSegment} </select> </mapper>
(2)然后在 mapper.java 中添加相应的接口方法即可:
public interface UserInfoMapper extends BaseMapper<UserInfo> { List<UserInfo> getAll(@Param(Constants.WRAPPER) Wrapper wrapper); }