• [MyBatisPlus]DQL编程控制①(条件查询)


    条件查询

    结构还是前文的结构这里不再多赘述。

    解决日志冗长的问题

    • 不过测试的时候,控制台打印的日志比较多,速度有点慢而且不利于查看运行结果,所以接下来我们把这个日志处理下:

      • 取消初始化spring日志打印,resources目录下添加logback.xml,名称固定,内容如下:

        
        <configuration>
        configuration>
        
        • 1
        • 2
        • 3

        说明:logback.xml的配置内容,不是我们学习的重点,如果有兴趣可以自行百度查询。

      • 取消MybatisPlus启动banner图标

        在这里插入图片描述

        application.yml添加如下内容:

        # mybatis-plus日志控制台输出
        mybatis-plus:
          configuration:
            log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
          global-config:
            banner: off # 关闭mybatisplus启动图标
        
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6
      • 取消SpringBoot的log打印

        在这里插入图片描述

        application.yml添加如下内容:

        spring:
          main:
            banner-mode: off # 关闭SpringBoot启动图标(banner)
        
        • 1
        • 2
        • 3

    解决控制台打印日志过多的相关操作可以不用去做,一般会被用来方便我们查看程序运行的结果。

    构建条件查询

    在进行查询的时候,我们的入口是在Wrapper这个类上,因为它是一个接口,所以我们需要去找它对应的实现类,关于实现类也有很多,说明我们有多种构建查询条件对象的方式:
    在这里插入图片描述

    1. 先来看第一种:QueryWrapper
    @SpringBootTest
    class Mybatisplus02DqlApplicationTests {
    
        @Autowired
        private UserDao userDao;
        
        @Test
        void testGetAll(){
            QueryWrapper qw = new QueryWrapper();
            qw.lt("age",18);
            List<User> userList = userDao.selectList(qw);
            System.out.println(userList);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • lt: 小于(<) ,最终的sql语句为

      SELECT id,name,password,age,tel FROM user WHERE (age < ?)
      
      • 1

    第一种方式介绍完后,有个小问题就是在写条件的时候,容易出错,比如age写错,就会导致查询不成功

    1. 接着来看第二种:QueryWrapper的基础上使用lambda
    @SpringBootTest
    class Mybatisplus02DqlApplicationTests {
    
        @Autowired
        private UserDao userDao;
        
        @Test
        void testGetAll(){
            QueryWrapper<User> qw = new QueryWrapper<User>();
            qw.lambda().lt(User::getAge, 10);//添加条件
            List<User> userList = userDao.selectList(qw);
            System.out.println(userList);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • User::getAget,为lambda表达式中的,类名::方法名,最终的sql语句为:
    SELECT id,name,password,age,tel FROM user WHERE (age < ?)
    
    • 1

    注意:构建LambdaQueryWrapper的时候泛型不能省。

    此时我们再次编写条件的时候,就不会存在写错名称的情况,但是qw后面多了一层lambda()调用

    1. 接着来看第三种:LambdaQueryWrapper
    @SpringBootTest
    class Mybatisplus02DqlApplicationTests {
    
        @Autowired
        private UserDao userDao;
        
        @Test
        void testGetAll(){
            LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>();
            lqw.lt(User::getAge, 10);
            List<User> userList = userDao.selectList(lqw);
            System.out.println(userList);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    这种方式就解决了上一种方式所存在的问题。

    多条件构建

    学完了三种构建查询对象的方式,每一种都有自己的特点,所以用哪一种都行,刚才都是一个条件,那如果有多个条件该如何构建呢?

    需求:查询数据库表中,年龄在10岁到30岁之间的用户信息

    @SpringBootTest
    class Mybatisplus02DqlApplicationTests {
    
        @Autowired
        private UserDao userDao;
        
        @Test
        void testGetAll(){
            LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>();
            lqw.lt(User::getAge, 30);
            lqw.gt(User::getAge, 10);
            List<User> userList = userDao.selectList(lqw);
            System.out.println(userList);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • gt:大于(>),最终的SQL语句为

      SELECT id,name,password,age,tel FROM user WHERE (age < ? AND age > ?)
      
      • 1
    • 构建多条件的时候,可以支持链式编程

      LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>();
      lqw.lt(User::getAge, 30).gt(User::getAge, 10);
      List<User> userList = userDao.selectList(lqw);
      System.out.println(userList);
      
      • 1
      • 2
      • 3
      • 4

    需求:查询数据库表中,年龄小于10或年龄大于30的数据

    @SpringBootTest
    class Mybatisplus02DqlApplicationTests {
    
        @Autowired
        private UserDao userDao;
        
        @Test
        void testGetAll(){
            LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>();
            lqw.lt(User::getAge, 10).or().gt(User::getAge, 30);
            List<User> userList = userDao.selectList(lqw);
            System.out.println(userList);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • or()就相当于我们sql语句中的or关键字,不加默认是and,最终的sql语句为:

      SELECT id,name,password,age,tel FROM user WHERE (age < ? OR age > ?)
      
      • 1

    null判定

    先来看一张图,

    在这里插入图片描述

    • 我们在做条件查询的时候,一般会有很多条件可以供用户进行选择查询。
    • 这些条件用户可以选择使用也可以选择不使用,比如我要查询价格在8000以上的手机
    • 在输入条件的时候,价格有一个区间范围,按照需求只需要在第一个价格输入框中输入8000
    • 后台在做价格查询的时候,一般会让 price>值1 and price <值2
    • 因为前端没有输入值2,所以如果不处理的话,就会出现 price>8000 and price < null问题
    • 这个时候查询的结果就会出问题,具体该如何解决?

    在这里插入图片描述

    需求:查询数据库表中,根据输入年龄范围来查询符合条件的记录

    用户在输入值的时候,

    ​ 如果只输入第一个框,说明要查询大于该年龄的用户

    ​ 如果只输入第二个框,说明要查询小于该年龄的用户

    ​ 如果两个框都输入了,说明要查询年龄在两个范围之间的用户

    思考第一个问题:后台如果想接收前端的两个数据,该如何接收?

    我们可以使用两个简单数据类型,也可以使用一个模型类,但是User类中目前只有一个age属性,如:

    @Data
    public class User {
        private Long id;
        private String name;
        private String password;
        private Integer age;
        private String tel;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    使用一个age属性,如何去接收页面上的两个值呢?这个时候我们有两个解决方案

    方案一:添加属性age2,这种做法可以但是会影响到原模型类的属性内容

    @Data
    public class User {
        private Long id;
        private String name;
        private String password;
        private Integer age;
        private String tel;
        private Integer age2;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    方案二:新建一个模型类,让其继承User类,并在其中添加age2属性,UserQuery在拥有User属性后同时添加了age2属性。

    @Data
    public class User {
        private Long id;
        private String name;
        private String password;
        private Integer age;
        private String tel;
    }
    
    @Data
    public class UserQuery extends User {
        private Integer age2;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    环境准备好后,我们来实现下刚才的需求:

    @SpringBootTest
    class Mybatisplus02DqlApplicationTests {
    
        @Autowired
        private UserDao userDao;
        
        @Test
        void testGetAll(){
            //模拟页面传递过来的查询数据
            UserQuery uq = new UserQuery();
            uq.setAge(10);
            uq.setAge2(30);
            LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>();
            if(null != uq.getAge2()){
                lqw.lt(User::getAge, uq.getAge2());
            }
            if( null != uq.getAge()) {
                lqw.gt(User::getAge, uq.getAge());
            }
            List<User> userList = userDao.selectList(lqw);
            System.out.println(userList);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    上面的写法可以完成条件为非空的判断,但是问题很明显,如果条件多的话,每个条件都需要判断,代码量就比较大,来看MP给我们提供的简化方式:

    @SpringBootTest
    class Mybatisplus02DqlApplicationTests {
    
        @Autowired
        private UserDao userDao;
        
        @Test
        void testGetAll(){
            //模拟页面传递过来的查询数据
            UserQuery uq = new UserQuery();
            uq.setAge(10);
            uq.setAge2(30);
            LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>();
            lqw.lt(null!=uq.getAge2(),User::getAge, uq.getAge2());
            lqw.gt(null!=uq.getAge(),User::getAge, uq.getAge());
            List<User> userList = userDao.selectList(lqw);
            System.out.println(userList);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    d当然这个也可以使用链式编程,如果太长了就要做些微的调整:
    在这里插入图片描述

    • lt()方法

      condition为boolean类型,返回true,则添加条件,返回false则不添加条件

  • 相关阅读:
    康耐视深度学习ViDi-Database菜单介绍
    宜家IKEA EDI IFTMBF运输预定请求详解
    流体动力润滑(轴承油膜承载机理)
    pandas使用dataframe中的两列时间对象数据列作差生成时间差数据列、指定时间数据列减去timedelta数据列实现数据偏移(向后偏移、时间减小)
    redis 性能这么好,你不完全知道
    【推荐系统】什么是好的推荐系统?个性化和非个性化推荐
    【linux】 第1回 linux运维基础
    android11使用google test
    下载测试视频
    15.项目讲解之前端页面的实现
  • 原文地址:https://blog.csdn.net/zyb18507175502/article/details/126031880