6. MyBatis-Plus条件构造器

一、wapper介绍

1、Wrapper家族

在MP中我们可以使用通用Mapper(BaseMapper)实现基本查询,也可以使用自定义Mapper(自定义XML)来实现更高级的查询。当然你也可以结合条件构造器来方便的实现更多的高级查询。

在这里插入图片描述

Wrapper : 条件构造抽象类,最顶端父类

AbstractWrapper : 用于查询条件封装,生成 sql 的 where 条件

​ QueryWrapper : 查询条件封装

​ UpdateWrapper : Update 条件封装

AbstractLambdaWrapper : 使用Lambda 语法

​ LambdaQueryWrapper :用于Lambda语法使用的查询Wrapper

​ LambdaUpdateWrapper : Lambda 更新封装Wrapper

2、创建测试类

WrapperTests.java

@SpringBootTest
public class WrapperTests {
    
    @Resource
    private UserMapper userMapper;
}

二、QueryWrapper

1、例1:组装查询条件

查询名字中包含n,年龄大于等于10且小于等于20,email不为空的用户

    @Test
    public void test1() {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper
                .like("username", "n")
                .between("age", 10, 20)
                .isNotNull("email");
        List<User> list = userMapper.selectList(queryWrapper);
        list.forEach(System.out::println);
    }

2、例2:组装排序条件

按年龄降序查询用户,如果年龄相同则按id升序排列

    @Test
    public void test2() {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.orderByDesc("age")
                .orderByAsc("uid");
        List<User> list = userMapper.selectList(queryWrapper);
        list.forEach(System.out::println);
    }

3、例3:组装删除条件

删除email为空的用户

    @Test
    public void test3() {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.isNull("email");
        int result = userMapper.delete(queryWrapper);
        System.out.println("删除了" + result + "条记录");
    }

4、例4:条件的优先级

查询名字中包含n,且(年龄小于18或email为空的用户),并将这些用户的年龄设置为18,邮箱设置为 user@indi.com

    @Test
    public void test4() {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper
                .like("username", "n")
                .and(i -> i.lt("age", 18).or().isNull("email"));

        User user = new User();
        user
                .setAge(18)
                .setEmail("user@indi.com");
        int result = userMapper.update(user, queryWrapper);
        System.out.println(result);
    }

5、例5:组装select子句

查询所有用户的用户名和年龄

@Test
public void test5() {
    QueryWrapper<User> queryWrapper = new QueryWrapper<>();
    queryWrapper.select("username", "age");
    
    //selectMaps()返回Map集合列表,通常配合select()使用,避免User对象中没有被查询到的列值为null
    List<Map<String, Object>> maps = userMapper.selectMaps(queryWrapper);
    maps.forEach(System.out::println);
}

6、例6:实现子查询

查询id不大于3的所有用户的id列表

    @Test
    public void test6() {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        // 这种方式容易引发SQL注入
        // String sql = "select uid from t_user where uid <= 3 or true";
        // queryWrapper.inSql("uid", sql);
		
		// 这种方式需要查询出所有id
        //queryWrapper.in("uid", 1, 2, 3);
        
        // 最推荐这种方式
        queryWrapper.le("uid", 3);
        
        List<User> userList = userMapper.selectList(queryWrapper);
        userList.forEach(System.out::println);
    }

三、UpdateWrapper

例7:需求同例4

查询名字中包含n,且(年龄小于18或email为空的用户),并将这些用户的年龄设置为18,邮箱设置为 user@indi.com

    @Test
    public void test7() {
        //组装set子句
        UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
        updateWrapper
            .set("age", 18)
            .set("email", "user@indi.com")
            .like("name", "n")
            .and(i -> i.lt("age", 18).or().isNull("email")); //lambda表达式内的逻辑优先运算
        //这里必须要创建User对象,否则无法应用自动填充。如果没有自动填充,可以设置为null
        User user = new User();
        int result = userMapper.update(user, updateWrapper);
        System.out.println(result);
    }

四、condition

例8:动态组装查询条件

查询名字中包含n,年龄大于10且小于20的用户,查询条件来源于用户输入,是可选的

    @Test
    public void test8() {

        //定义查询条件,有可能为null(用户未输入)
        String name = null;
        Integer ageBegin = 10;
        Integer ageEnd = 20;
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        if(StringUtils.isNotBlank(name)){
            queryWrapper.like("name","n");
        }
        if(ageBegin != null){
            queryWrapper.ge("age", ageBegin);
        }
        if(ageEnd != null){
            queryWrapper.le("age", ageEnd);
        }
        List<User> users = userMapper.selectList(queryWrapper);
        users.forEach(System.out::println);
    }

上面的实现方案没有问题,但是代码比较复杂,我们推荐使用带condition参数的重载方法构建查询条件,简化代码的编写

    @Test
    public void test8Condition() {
        //定义查询条件,有可能为null(用户未输入)
        String name = null;
        Integer ageBegin = 10;
        Integer ageEnd = 20;
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper
            .like(StringUtils.isNotBlank(name), "name", "n")
            .ge(ageBegin != null, "age", ageBegin)
            .le(ageEnd != null, "age", ageEnd);
        List<User> users = userMapper.selectList(queryWrapper);
        users.forEach(System.out::println);
    }

五、LambdaXxxWrapper

1、例9:Query - 需求同例8

    @Test
    public void test9() {
        //定义查询条件,有可能为null(用户未输入)
        String name = null;
        Integer ageBegin = 10;
        Integer ageEnd = 20;
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper
            //避免使用字符串表示字段,防止运行时错误
            .like(StringUtils.isNotBlank(name), User::getName, "n")
            .ge(ageBegin != null, User::getAge, ageBegin)
            .le(ageEnd != null, User::getAge, ageEnd);
        List<User> users = userMapper.selectList(queryWrapper);
        users.forEach(System.out::println);
    }

2、例10:Update - 需求同例4

    @Test
    public void test10() {
        //组装set子句
        LambdaUpdateWrapper<User> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper
            .set(User::getAge, 18)
            .set(User::getEmail, "user@indi.com")
            .like(User::getName, "n")
            .and(i -> i.lt(User::getAge, 18).or().isNull(User::getEmail)); //lambda表达式内的逻辑优先运算

        User user = new User();
        int result = userMapper.update(user, updateWrapper);
        System.out.println(result);
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值