Mapper的CRUD接口2:条件构造器

1、相等、不相等

  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();
  1. 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();
  1. 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();
  1. notLike 表示不包含指定的值(not like ‘%值%’
List<UserInfo> userInfos = new LambdaQueryChainWrapper<>(userInfoMapper)
        .notLike(UserInfo::getUserName, "xxname") // user_name not like '%xxname%'
        .list();

4、是否为 null

isNull 表示字段是否为 nullis null),isNotNull 表示字段是否不为 nullis 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();
  1. 下面是 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、分组、筛选

下面是 groupByhaving 的用法:

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();
  1. orandnested 可以实现带嵌套的查询:
  • orOR 嵌套
  • andAND 嵌套
  • 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 注入)

  1. 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();
  1. 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();
  1. 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-plus3.0.7 版本之后,也支持自定义 SQL 语句使用 Wrapper,具体有如下两种方案。注意:使用 Wrapper 的话自定义 sql 中不能有 WHERE 语句。

  1. 注解方式(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)
);
  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>