• 04条件构造器和常用接口


    条件构造器和常用接口

    wapper介绍

    在这里插入图片描述
    条件构造器的两个条件之间默认就是AND并列关系,如果需要或者的关系则需要调用构造器的or()方法

    条件构造器类型作用
    Wrapper条件构造抽象类,最顶端父类
    AbstractWrapper生成SQL的where条件
    QueryWrapper封装查询或删除的条件
    UpdateWrapper封装修改的条件和要修改的字段的值
    AbstractLambdaWrapper使用Lambda语法,生成SQL的where条件
    LambdaQueryWrapper使用Lambda语法封装查询或删除的条件
    LambdaUpdateWrapper使用Lambda语法封装修改的条件和要修改的字段

    支持传入条件构造器的CRUD方法

    int delete(@Param(Constants.WRAPPER) Wrapper<T> wrapper);
    // 如果设置了修改的字段,实体类可以为null
    int update(@Param(Constants.ENTITY) T entity, @Param(Constants.WRAPPER) Wrapper<T> updateWrapper);
    T selectOne(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
    List<T> selectList(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
    // 根据Wrapper条件查询全部记录
    List<Map<String, Object>> selectMaps(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
    // 根据Wrapper条件查询全部记录(返回第一个字段的值)
    List<Object> selectObjs(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
    // 分页查询
    IPage<T> selectPage(IPage<T> page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
    // 根据Wrapper条件,查询全部记录并翻页
    IPage<Map<String, Object>> selectMapsPage(IPage<T> page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
    // 根据Wrapper条件,查询总记录数
    Integer selectCount(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    QueryWrapper

    由于这些方法的返回值最后都是QueryWrapper对象所以都支持链式结构的调用

    方法名功能
    QueryWrapper between(数据库表中字段,最小值,最大值)查询指定范围的区间包括边界值
    QueryWrapper gt/ge(数据库表中字段,值)gt表示查询大于区间,ge表示查询大于等于区间(e表示equal的意思)
    QueryWrapper lt/le(数据库表中字段,值)lt表示查询小于区间,le表示查询小于等于区间
    QueryWrapper eq/ne(数据库表中字段,值)eq表示查询字段等于某个值的记录,ne表示查询字段不等于某个值的记录
    QueryWrapper in()包含哪几个值
    QueryWrapper orderByDesc(数据库表中字段)对查询到的结果按照字段降序排序
    QueryWrapper orderByAsc(数据库表中字段)对查询到的结果按照字段升序排序
    方法名功能
    QueryWrapper like(数据库表中字段,值)模糊查询
    QueryWrapper isNotNull/isNull(数据库表中字段)判断某个字段值为不为空
    QueryWrapper and(Consumer< Param>,consumer)相当于在待执行的SQL语句前加了一个括号,Param参数是wrapper的子类即条件构造器
    QueryWrapper or()使用or关键字连接条件,默认调用方法是使用and关键字连接条件但不加括号
    QueryWrapper select(数据库字段…)指定要查询的字段,selectList方法默认是查询所有的字段
    QueryWrapper inSql(数据库字段,查询语句)以某次查询结果为基础再次查询

    使用QueryWrapper条件构造器封装查询的条件实现查询和排序功能

    @Data
    public class User {
        private Long id;
        @TableFiled("user_name")
        private String name;
        private Integer age;
        private String email;
        @TableLogic
        private Integer isDeleted;  
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    @springBootTest
    public class MybatisPlusWrapperTest{
        @Autowired
        private UserMapper userMapper;
        //查询用户名包含a,年龄在20到30之间,并且邮箱不为null的用户信息
        /*
        SELECT 
           id,user_name AS name,age,email,is_deleted 
        FROM 
           t_user 
        WHERE 
           is_deleted=0 AND (user_name LIKE ? AND age BETWEEN ? AND ? AND email IS NOT NULL)
        */
        @Test
        public void test01(){
            QueryWrapper<User> queryWrapper = new QueryWrapper<>();
            //链式结构的调用,这些方法的返回值最后都是queryWrapper对象
            queryWrapper.like("user_name", "a").between("age", 20, 30).isNotNull("email");
            //将查询的结果集映射到实体类的属性最后一起放入List集合当中(一条记录对应一个User对象)
            List<User> list = userMapper.selectList(queryWrapper);
            list.forEach(System.out::println);
        }
        //按年龄降序查询用户,如果年龄相同则按id升序排列
        /*
        SELECT 
           id,user_name AS name,age,email,is_deleted 
        FROM 
           t_user 
        WHERE 
           is_deleted=0 ORDER BY age DESC,id ASC
        */
        @Test
        public void test02(){
            QueryWrapper<User> queryWrapper = new QueryWrapper<>();
           	queryWrapper.orderByDesc("age").orderByAsc("id");
            List<User> users = userMapper.selectList(queryWrapper);
            users.forEach(System.out::println);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    // 查询用户名包含a,年龄在20到30之间,并且邮箱不为null的用户信息
    User(id=4,name=Sandy,age=21,email=test4@baomidou.com,isDeleted=0)
    
    //按年龄降序查询用户,如果年龄相同则按id升序排列    
    User(id=5,name=Billie, age=24, email=test5@baomidou.com, isDeleted=0)
    User(id=6,name=张三,age=23,email=zhangsan@atguigu.com,isDeleted=0)
    User(id=100,name=张三,age=23,Iemail=zhangsan@atguigu.com,isDeleted=0)
    User(id=101,name=张三,age=23,email=zhangsan@atguigu.com,isDeleted=0)
    User(id=102,name=张三,age=23,email=zhangsan@atguigu.com,isDeleted=0)
    User(id=103,name=张三,age=23,email=zhangsan@atguigu.com,isDeleted=0
    User(id=104,name=张三,age=23,email=zhangsan@atguigu.com,isDeleted=0)
    User(id=4,name=Sandy,age=21,email=test4@baomidou.com,isDeleted=0)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    使用QueryWrapper条件构造器封装删除的条件实现删除功能(逻辑删除)

    //删除email为空的用户
    /*
    UPDATE
    	t_user 
    SET 
    	is_deleted=1 
    WHERE 
    	is_deleted=0 AND (email IS NULL)
    */
    @Test
    public void test03(){
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.isNull("email");
        int result = userMapper.delete(queryWrapper);
        System.out.println("受影响的行数:" + resu	lt);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    使用QueryWrapper条件构造器指定修改的条件配合实体类指定修改的字段实现修改功能

    //将(年龄大于20并且用户名中包含有a)或邮箱为null的用户信息修改
    /*
    UPDATE 
    	t_user 
    SET 
    	age=?, email=? 
    WHERE 
    	is_deleted = 0 AND (user_name LIKE ? AND age > ? OR email IS NULL)
    */
    @Test
    public void test04() {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper
        	.like("user_name", "a")
            .gt("age", 20)
            .or()
            .isNull("email");
        // 使用实体类指定要修改的字段
        User user = new User();
        user.setAge(18);
        user.setEmail("user@atguigu.com");
        int result = userMapper.update(user, queryWrapper);
        System.out.println("受影响的行数:" + result);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    使用QueryWrapper条件构造器查询数据表中特定的字段(selectList方法默认查询所有字段)

    //查询用户信息的user_name和age字段
    /*
    SELECT 
    	user_name,age,email 
    FROM 
    	t_user 
    WHERE 
    	is_deleted=0
    */
    @Test
    public void test05() {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("user_name", "age","email");
        //selectMaps()方法将查询的结果集以key(字段名)=value(字段值)的形式存到Map集合当中最后一起放入List集合(一条记录对应一个Map集合)
        List<Map<String, Object>> maps = userMapper.selectMaps(queryWrapper);
        maps.forEach(System.out::println);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    //查询用户信息的user_name和age字段,并将一条记录封装到一个Map集合中
    {user_name=小明,age=21,email=test@atguigu.com}
    {user_nameBillie,age=24, email=test5@baomidou.com}
    {user_name=张三,age=23,email=zhangsan@atguigu.com}
    {user_name=张三,age=23,email=zhangsan@atguigu.com}
    {user_name=张三,age=23,email=zhangsan@atguigu.com}
    {user_name=张三,age=23,email=zhangsan@atguigu.com}
    {user_name=张三,age=23,email=zhangsan@atguigu.com}
    {user_name=张三,age=23,email=zhangsan@atguigu.com}
    {user_name=小红,email=test@atguigu.com}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    使用QueryWrapper条件构造器组装子查询(以某次查询结果为基础上再次查询)

    // 查询id小于等于3的用户信息
    /*
    SELECT 
    	id,user_name,age,email,is_deleted 
    FROM 
    	t_user
    WHERE 
    	is_deleted=0 AND (id IN(select id from t_user where id <= 3))
    */
    @Test
    public void test06() {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        //第一个参数是子查询要比较的字段,第二个参数是SQL查询语句,就是将要比较字段在查询的结果上再一次筛选
        queryWrapper.inSql("id", "select id from t_user where id <= 3");
        List<User> list = userMapper.selectList(queryWrapper);
        list.forEach(System.out::println);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    条件构造器优先级

    条件构造器中封装的条件默认按照从左到右的顺序执行,调用构造器的and(Consumer> consumer)方法可以加小括号设置优先级

    • 在and方法内使用lambda表达式中可以保证条件优先执行,方法的参数我们就是要操作的条件构造器
    // 将用户名中包含有a并且(年龄大于20或邮箱为null)的用户信息修改
    /*
    UPDATE 
    	t_user 
    SET 
    	age=?, email=? 
    WHERE 
    	is_deleted=0 AND (user_name LIKE ? AND (age > ? OR email IS NULL))
    */
    @Test
    public void test04() {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        //queryWrapper.like("user_name", "a").and((QueryWrapper i){return i.gt("age", 20).or().isNull("email")});
        queryWrapper.like("user_name", "a").and(i -> i.gt("age", 20).or().isNull("email"));
        //设置实体类中要修改的字段,没设置的字段不会被修改
        User user = new User();
        user.setAge(20);
        user.setEmail("user@atguigu.com");
        int result = userMapper.update(user, queryWrapper);
        System.out.println("受影响的行数:" + result);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    UpdateWrapper

    方法名功能
    UpdateWrapper set(数据库字段,值)设置要修改的字段及其值

    使用UpdateWrapper不仅可以设置修改的条件还可以设置要修改的字段即不用再像QurreyWrapper一样创建实体类对象

    //将用户名中包含有a并且(年龄大于20或邮箱为null)的用户信息修改
    /*
    UPDATE 
    	t_user 
    SET 
    	age=?,email=? 
    WHERE 
    	is_deleted=0 AND (user_name LIKE ? AND(age > ? OR email IS NULL))
    */
    @Test
    public void test07() {
        UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
        //设置修改的字段及其对应的值
        updateWrapper.set("age", 18).set("email", "user@atguigu.com");
        //设置修改的条件,lambda表达式内的逻辑优先运算
        updateWrapper.like("user_name", "a").and(i -> i.gt("age", 20).or().isNull("email"));
        //设置修改的条件和字段简写
        /*updateWrapper.set("age", 18).set("email", "user@atguigu.com")
        			   .like("user_name", "a")
        			   .and(i -> i.gt("age", 20).or().isNull("email"));*/
        //由于之前设置了修改的字段,所以此时不再需要传递实体类参数直接传递null即可
        int result = userMapper.update(null, updateWrapper);
        System.out.println(result);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    condition组装条件(动态SQL)

    在开发的过程中一些SQL条件来源于用户的选择,因此最终在执行SQL语句时必须先判断用户是否选择了某些条件,若选择了则拼接该SQL条件若没有选择则不拼接

    方法名功能
    boolean isNotBlank(Sting string)判断某字符串是否不为空字符串"",不为null,不为空白符,总之如果字符串没有数据就返回false
    QueryWrapper like(condition判断条件,数据库表中字段,值)如果判断条件返回为true,则组装后面的条件进行模糊查询

    传统方式: 使用if语句做判断拼装查询的条件

    // 根据年龄和username查询用户信息,其中username为null
    /*
    SELECT 
    	id,user_name AS name,age,email,is_deleted 
    FROM 
    	t_user 
    WHERE 
    	is_deleted=0 AND (age >=? AND age <= ?)
    */
    @Test
    public void test08() {
        // 查询条件有可能为null(用户未输入或未选择)
        String username = null;
        Integer ageBegin = 10;
        Integer ageEnd = 24;
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        //StringUtils是由Mybatis-pius提供判断字符串是由有无数据的工具类
        if(StringUtils.isNotBlank(username)){
            queryWrapper.like("user_name",username);
        }
        if(ageBegin != null){
            queryWrapper.ge("age", ageBegin);
        }
        if(ageEnd != null){
            queryWrapper.le("age", ageEnd);
        }
        //由于username为null所以只有年龄作为条件
        List<User> users = userMapper.selectList(queryWrapper);
        users.forEach(System.out::println);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    调用条件构造器的条件方法时直接额外传递一个condition判断条件参数即一个bollean类型的值,如果条件为true表示组装后面的条件fasle则不组装

    /*
    SELECT 
    	id,user_name AS name,age,email,is_deleted 
    FROM 
    	t_user 
    WHERE 
    	is_deleted=0 AND (user_name like ? AND age <= ?)
    */
    @Test
    public void test08UseCondition() {
        //查询条件有可能为null(用户未输入或未选择)
        String username = "a";
        Integer ageBegin = null;
        Integer ageEnd = 24;
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        //方法的参数传入condition判断条件
        queryWrapper.like(StringUtils.isNotBlank(username), "user_name", username).ge(ageBegin != null, "age", ageBegin)							.le(ageEnd != null, "age", ageEnd);
        List<User> users = userMapper.selectList(queryWrapper);
        users.forEach(System.out::println);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    LambdaQuery/UpdateWrapper

    当使用字符串指定一个字段时容易写错导致运行时出现错误

    LambdaQuery/UpdateWrapper的条件方法中另外提供了一个函数式接口Function(实体类,?),我们可以直接访问实体类的某个属性从而获取对应字段作为条件

    • 使用LambdaQuery/UpdateWrapper的条件构造器必须使用函数式接口指定字段名

    类::实例方法: 抽象方法a在被重写时使用了某一个对象的方法b,如果方法a和b的返回值类型相同但方法b的形参少一个,则可以使用方法b实现对方法a的重写替换

    • Function中的R apply(T t)方法和User中的R getXxx()方法
    方法名功能
    QueryWrapper like(condition判断条件,Function(实体类,?),值)通过访问实体类的属性获取属性对应的字段做模糊查询

    使用LambdaQueryWrapper

    // 查询用户名包含有a,年龄在10-24之间的用户
    /*
    SELECT 
    	id,user_name AS name,age,email,is_deleted 
    FROM 
    	t_user 
    WHERE 
    	(user_name LIKE ? age >=? AND age <= ?)
    */
    @Test
    public void test09() {
        String username = "a";
        Integer ageBegin = 10;
        Integer ageEnd = 24;
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(StringUtils.isNotBlank(username), User::getName, username).ge(ageBegin != null, User::getAge, ageBegin)
            .le(ageEnd != null, User::getAge, ageEnd);
        List<User> users = userMapper.selectList(queryWrapper);
        users.forEach(System.out::println);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    使用LambdaUpdateWrapper

    //将用户名中包含有a并且(年龄大于20或邮箱为null)的用户信息修改
    /*
    UPDATE 
    	t_user 
    SET 
    	age=?,email=? 
    WHERE 
    	is_deleted=0 AND (user_name LIKE ? AND(age > ? OR email IS NULL))
    */
    @Test
    public void test10() {
        LambdaUpdateWrapper<User> updateWrapper = new LambdaUpdateWrapper<>();
        //设置修改的条件和字段
        updateWrapper.set(User::getAge, 18).set(User::getEmail, "user@atguigu.com")
            .like(User::getName, "a")
            .and(i -> i.lt(User::getAge, 24).or().isNull(User::getEmail)); 
        int result = userMapper.update(null, updateWrapper);
        System.out.println("受影响的行数:" + result);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
  • 相关阅读:
    C#小知识
    GitHub 毕业年鉴「GitHub 热点速览 v.22.20」
    puzzle(018.4)珍珑棋局
    java-net-php-python-springboot办公自动化系统计算机毕业设计程序
    OpenNebula的配置与应用(一)
    Dockerfil 构建上下文 build -f 选项 加快构建速度
    Jtti:Linux大文件重定向和管道的效率哪个更高
    新生任务-1
    powershell 搜索文本并返回行号
    Java 语法糖以及常见的应用
  • 原文地址:https://blog.csdn.net/qq_57005976/article/details/132922825