Mapper的CRUD接口2:条件构造器
1、相等、不相等
- allEq 表示全部 eq(或个别 isNull)
方法最后一个参数 null2IsNull是可选的(默认为true),为 true时则在map的value为null时调用isNull方法,为false时则忽略:
• allEq({id:1,user_name:“xxname”,age:null}) — 生成的sql为 —> id = 1 and user_name = ‘xxname’ and age is null
• allEq({id:1,user_name:“xxname”,age:null}, false) — 生成的sql为 —> id = 1 and user_name = 'xxname’
Map<SFunction<UserInfo, ?>, Object> map = new HashMap<>();
map.put(UserInfo::getId, 3);
map.put(UserInfo::getUserName, "xxname");
map.put(UserInfo::getAge, null);
List<UserInfo> userInfos = new LambdaQueryChainWrapper<>(userInfoMapper)
.allEq(map)
.list();
- eq 表示等于(=),ne 表示不等于(<>)
List<UserInfo> userInfos = new LambdaQueryChainWrapper<>(userInfoMapper)
.eq(UserInfo::getId, 1) // id = 1
.ne(UserInfo::getAge, 22) // age <> 22
.list();
2、大于、小于
- 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();
- 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、模糊查询
- 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();
- notLike 表示不包含指定的值(not like ‘%值%’)
List<UserInfo> userInfos = new LambdaQueryChainWrapper<>(userInfoMapper)
.notLike(UserInfo::getUserName, "xxname") // user_name not like '%xxname%'
.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 注入)
- 下面是 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();
- 下面是 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
- 主动调用 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();
- or、 and、nested 可以实现带嵌套的查询:
- or 为 OR 嵌套
- and 为 AND 嵌套
- nested 为正常嵌套(不带 AND 或者 OR)
// WHERE age IS NOT NULL AND ((id = 1 AND user_name = 'xxname') OR (id = 2 AND user_name = 'xxname'))
List<UserInfo> userInfos = new LambdaQueryChainWrapper<>(userInfoMapper)
.isNotNull(UserInfo::getAge)
.and(i -> i.nested(
j -> j.eq(UserInfo::getId,1).eq(UserInfo::getUserName,"xxname")
)
.or(j -> j.eq(UserInfo::getId,2).eq(UserInfo::getUserName,"xxname"))
)
.list();
10、拼接 sql(sql 注入)
- apply 方法可以直接将自定义的 sql 拼接到查询条件中:
// WHERE age IS NOT NULL AND id = 3 AND user_name = 'xxname'
List<UserInfo> userInfos = new LambdaQueryChainWrapper<>(userInfoMapper)
.isNotNull(UserInfo::getAge)
.apply("id = 3") // 有sql注入的风险
.apply("user_name = {0}", "xxname") //无sql注入的风险
.list();
- 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
- 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();
- 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();
13、自定义 SQL 语句使用 Wrapper
mybatis-plus 在 3.0.7 版本之后,也支持自定义 SQL 语句使用 Wrapper,具体有如下两种方案。注意:使用 Wrapper 的话自定义 sql 中不能有 WHERE 语句。
- 注解方式(Mapper.java)
- 我们可以直接在自定义方法上使用 @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)
);
- XML 形式(Mapper.xml)
- 首先在 mapper.java 中添加相应的接口方法即可:
public interface UserInfoMapper extends BaseMapper<UserInfo> {
List<UserInfo> getAll(@Param(Constants.WRAPPER) Wrapper wrapper);
}
- 然后在 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>