返回 导航

SpringBoot / Cloud

hangge.com

SpringBoot - MyBatis-Plus使用详解5(Mapper的CRUD接口2:条件构造器)

作者:hangge | 2020-05-13 08:10

五、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 表示字段是否为 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();

(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)orandnested 可以实现带嵌套的查询:
  • 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 拼接到查询条件中:
// 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-plus3.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);
}

(2)下面调用这个自定义方法:
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);
}
评论

全部评论(0)

回到顶部