【MybatisPlus快速入门】—— 进阶入门

这篇具有很好参考价值的文章主要介绍了【MybatisPlus快速入门】—— 进阶入门。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

进阶篇

1.1 映射专题

  • Mybatis 框架之所以能够简化数据库操作,是因为他内部的映射机制,通过自动映射,进行数据的封装,我们只要符合映射规则,就可以快速高效的完成SQL操作的实现
  • 既然 MybatisPlus 是基于Mybatis 的增强工具,所以也具有这样的映射规则

1.1.1 自动映射

  • 表名和实体类名映射 -> 表名user 实体类名User 【类名首字母小写后和表名相同】
  • 字段名和实体类属性名映射 -> 字段名name 实体类属性名name 【字段名和属性名相同】
  • 字段名下划线命名方式和实体类属性小驼峰命名方式映射 -> 字段名 user_email 实体类属性名 userEmail
    • MybatisPlus 支持这种映射规则,可以通过配置来设置 【在SpringBoot核心配置文件进行配置】
    map-underscore-to-camel-case: true 表示支持下划线到驼峰的映射
    map-underscore-to-camel-case: false 表示不支持下划线到驼峰的映射
    

1.1.2 表映射

  • 如果我们的表名和实体类名不一致怎么办?
    • 通过 @TableName() 注解指定映射的数据库表名,就会按照指定的表名进行映射

    • 如:此时将数据库的表名改为powershop_user,要完成表名和实体类名的映射,需要将实体类名也要指定为 powershop_user

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    @TableName("powershop_user")
    public class User {
        private Long id;
        private String name;
        private Integer age;
        private String email;
    }
    
  • 如果有很多实体类,对应到数据库中的很多表,我们不需要每个依次配置,只需要配置一个全局的设置,他都会给每个实体类名前面添加指定的前缀,这里我们演示一下全局配置的效果
mybatis-plus:
  global-config:
    db-config:
      table-prefix: powershop_

1.1.3 字段映射

  • 表映射说明了表名与实体类名不一致的解决方法,那么什么场景下会改变字段映射呢?

  • 当数据库字段和表实体类的属性不一致时,我们可以使用 @TableField() 注解改变字段和属性的映射,让注解中的名称和表字段保持一致

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class User {
        @TableField("username")
        private String name;
    }
    
  • 数据库字段和表实体类的属性一致,但是字段名为关键字,不能直接用于sql查询

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class User {
        @TableField("`desc`")
        private String desc;
    }
    

1.1.4 字段失效

  • 当数据库中有字段不希望被查询,我们可以通过@TableField(select = false)来隐藏这个字段,那在拼接SQL语句的时候,就不会拼接这个字段
    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class User {
        @TableField(select = false)
        private Integer age;
    }
    

【MybatisPlus快速入门】—— 进阶入门

1.1.5 视图属性

  • 在实际开发中,有些字段不需要数据库存储,但是却需要展示,需要展示也就是意味着实体类中需要存在这个字段,我们称这些实体类中存在但是数据库中不存在的字段,叫做视图字段

  • 根据之前的经验,框架会默认将实体类中的属性作为查询字段进行拼接,那我们来思考,像这种视图字段,能够作为查询条件么,显示是不能的。因为数据库中没有这个字段,所以查询字段如果包含这个字段,SQL语句会出现问题

  • 我们通过 @TableField(exist = false) 来去掉这个字段,不让他作为查询字段

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class User {
        @TableField(exist = false)
        private Integer online;
    }
    

【MybatisPlus快速入门】—— 进阶入门

1.2 条件构造器

  • 什么是条件构造器?
    • 条件构造器(Wrapper)是MyBatisPlus框架提供的一种方便的查询构建器,用于构建复杂的查询条件。
    • 它是基于Lambda表达式的,可以使用面向对象的方式构建查询条件,不需要写复杂的SQL语句,大大简化了数据库操作代码的编写。

1️⃣ 条件构造器图谱
【MybatisPlus快速入门】—— 进阶入门

2️⃣ 展开介绍

  • Wrapper 抽象类,条件类的顶层,提供了一些获取和判断相关的方法
  • AbstractWrapper 抽象类,Wrapper的子类,提供了所有的条件相关方法
  • AbstractLambdaWrapper 抽象类,AbstractWrapper的子类,确定字段参数为方法引用类型
  • QueryWrapper 类,AbstractWrapper的子类,如果我们需要传递String类型的字段信息,创建该对象
  • LambdaQueryWrapper 类,AbstractLambdaWrapper的子类,如果我们需要传递方法引用方式的字段信息,创建该对象

3️⃣ 我们在编写代码的时候,只需要关注QueryWrapper和LambdaQueryWrapper

1.3 查询专题

1.3.1 等值查询

1️⃣ eq 等值查询

(1)使用QueryWrapper对象,构建查询条件

@Test
    void eq() {
        //创建我们QueryWrapper对象 [创建条件查询对象]
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        //添加我们的查询条件 [此处演示的是等值查询] [设置查询条件,指定查询字段和匹配的值]
        userQueryWrapper.eq("name", "Jack");
        //调用我们的接口对象的方法 [进行条件查询]
        User user = userMapper.selectOne(userQueryWrapper);
        System.out.println(user);
    }

【MybatisPlus快速入门】—— 进阶入门

(2)使用 LambdaQueryWrapper 对象,构建查询条件

  • 在构建字段时,使用方法引用的方式来选择字段,这样做可以避免字段拼写错误出现问题
@Test
    void eq2() {
        LambdaQueryWrapper<User> userLambdaQueryWrapper = new LambdaQueryWrapper<>();
        userLambdaQueryWrapper.eq(User::getName, "Jack");
        User user = userMapper.selectOne(userLambdaQueryWrapper);
        System.out.println(user);
    }

【MybatisPlus快速入门】—— 进阶入门

  • 还要考虑一种情况,我们构建的条件是从哪里来的?

    • 应该是从客户端通过请求发送过来的,由服务端接收的。
    • 在网站中一般都会有多个条件入口,用户可以选择一个或多个条件进行查询,那这个时候在请求时,我们不能确定所有的条件都是有值的,部分条件可能用户没有传值,那该条件就为null。
      • 比如在电商网站中,可以选择多个查询条件
  • 那为null的条件,我们是不需要进行查询条件拼接的,否则就会出现如下情况,将为null的条件进行拼接,筛选后无法查询出结果

@Test
    void isNull() {
        LambdaQueryWrapper<User> userLambdaQueryWrapper = new LambdaQueryWrapper<>();
        userLambdaQueryWrapper.eq(User::getName, null);
        User user = userMapper.selectOne(userLambdaQueryWrapper);
        System.out.println(user);
    }

【MybatisPlus快速入门】—— 进阶入门

  • 当然我们要解决这个问题,可以先判断是否为空,根据判断结果选择是否拼接该字段,这个功能其实不需要我们写,由MybatisPlus的方法已经提供好了。

【MybatisPlus快速入门】—— 进阶入门

@Test
    void isNull2() {
        LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        String name = null;
        lambdaQueryWrapper.eq(name != null, User::getName, name);
        List<User> users = userMapper.selectList(lambdaQueryWrapper);
        System.out.println(users);
    }

【MybatisPlus快速入门】—— 进阶入门

2️⃣ allEq

(1)先演示一下如何通过多个eq,构建多条件查询【这部分也可以采用链式调用】

@Test
    void allEq1() {
        LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(User::getName, "Tom");
        lambdaQueryWrapper.eq(User::getAge, 28);
        User user = userMapper.selectOne(lambdaQueryWrapper);
        System.out.println(user);
    }

【MybatisPlus快速入门】—— 进阶入门

(2)如果此时有多个条件需要同时判断,我们可以将这多个条件放入到Map集合中,更加的方便

@Test
    void allEq2() {
        //创建一个集合来保存我们的多个查询条件
        HashMap<String, Object> hashMap = new HashMap<>();
        hashMap.put("name", "Tom");
        //此处测试修改参数值为null
        hashMap.put("age", null);
        //此时不能使用我们的LambdaQueryWrapper了,只能用QueryWrapper
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.allEq(hashMap, true);
        User user = userMapper.selectOne(queryWrapper);
        System.out.println(user);
    }
  • allEq(Map<R, V> params, boolean null2IsNull)

    • 参数params:表示传递的Map集合
    • 参数null2IsNull:表示对于为null的条件是否判断isNull
  • 第二个参数设置为 false 的效果就是如果字段值为空,那么就不会拼接为查询条件
    【MybatisPlus快速入门】—— 进阶入门

3️⃣ ne 不等查询

@Test
    void ne() {
        LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.ne(User::getName, "Tom");
        List<User> users = userMapper.selectList(lambdaQueryWrapper);
        System.out.println(users);
    }

【MybatisPlus快速入门】—— 进阶入门

1.3.2 范围查询

1️⃣ gt 大于

@Test
    void gt() {
        LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.gt(User::getAge, 19);
        List<User> users = userMapper.selectList(lambdaQueryWrapper);
        System.out.println(users);
    }

【MybatisPlus快速入门】—— 进阶入门

2️⃣ ge 大于等于

@Test
    void ge() {
        LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.ge(User::getAge, 18);
        List<User> users = userMapper.selectList(lambdaQueryWrapper);
        System.out.println(users);
    }

【MybatisPlus快速入门】—— 进阶入门

3️⃣ lt 小于

@Test
    void lt() {
        LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.lt(User::getAge, 19);
        List<User> users = userMapper.selectList(lambdaQueryWrapper);
        System.out.println(users);
    }

【MybatisPlus快速入门】—— 进阶入门

4️⃣ le 小于等于

@Test
    void le() {
        LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.le(User::getAge, 20);
        List<User> users = userMapper.selectList(lambdaQueryWrapper);
        System.out.println(users);
    }

【MybatisPlus快速入门】—— 进阶入门

5️⃣ between 在范围内 【包括端点值】

@Test
    void between() {
        LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.between(User::getAge, 18, 21);
        List<User> users = userMapper.selectList(lambdaQueryWrapper);
        System.out.println(users);
    }

【MybatisPlus快速入门】—— 进阶入门

6️⃣ notBetween 不在范围内

@Test
    void notBetween() {
        LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.notBetween(User::getAge, 18, 21);
        List<User> users = userMapper.selectList(lambdaQueryWrapper);
        System.out.println(users);
    }

【MybatisPlus快速入门】—— 进阶入门

1.3.3 模糊查询

1️⃣ like 模糊查询

@Test
    void like() {
        LambdaQueryWrapper<User> userLambdaQueryWrapper = new LambdaQueryWrapper<>();
        userLambdaQueryWrapper.like(User::getName, "j");//全模糊匹配,只要包含J
        List<User> users = userMapper.selectList(userLambdaQueryWrapper);
        System.out.println(users);
    }

【MybatisPlus快速入门】—— 进阶入门

2️⃣ notLike 模糊查询

@Test
    void notLike() {
        LambdaQueryWrapper<User> userLambdaQueryWrapper = new LambdaQueryWrapper<>();
        userLambdaQueryWrapper.notLike(User::getName, "j");//全模糊匹配,只要包含J
        List<User> users = userMapper.selectList(userLambdaQueryWrapper);
        System.out.println(users);
    }

【MybatisPlus快速入门】—— 进阶入门

3️⃣ likeLeft 模糊查询 【以XXX结尾】

@Test
    void likeLeft() {
        LambdaQueryWrapper<User> userLambdaQueryWrapper = new LambdaQueryWrapper<>();
        userLambdaQueryWrapper.likeLeft(User::getName, "e");//以XX结尾
        List<User> users = userMapper.selectList(userLambdaQueryWrapper);
        System.out.println(users);
    }

【MybatisPlus快速入门】—— 进阶入门

4️⃣ likeRight 模糊查询【以XXX开头】

@Test
    void likeRight() {
        LambdaQueryWrapper<User> userLambdaQueryWrapper = new LambdaQueryWrapper<>();
        userLambdaQueryWrapper.likeRight(User::getName, "J");//以XX开头
        List<User> users = userMapper.selectList(userLambdaQueryWrapper);
        System.out.println(users);
    }

【MybatisPlus快速入门】—— 进阶入门

1.3.4 判空查询

1️⃣ isNull 是否为空

@Test
    void isNull3() {
        LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.isNull(User::getName);
        List<User> users = userMapper.selectList(lambdaQueryWrapper);
        System.out.println(users);
    }

【MybatisPlus快速入门】—— 进阶入门

2️⃣ isNotNull 是否不为空

@Test
    void isNotNull() {
        LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.isNotNull(User::getName);
        List<User> users = userMapper.selectList(lambdaQueryWrapper);
        System.out.println(users);
    }

【MybatisPlus快速入门】—— 进阶入门

1.3.5 包含查询

1️⃣ in 包含在范围内 【也可以用or实现】

@Test
    void in() {
        LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        ArrayList<Integer> arrayList = new ArrayList<>();
        Collections.addAll(arrayList, 18, 20, 21);
        lambdaQueryWrapper.in(User::getAge, arrayList);
        List<User> users = userMapper.selectList(lambdaQueryWrapper);
        System.out.println(users);
    }

【MybatisPlus快速入门】—— 进阶入门

2️⃣ notIn 不包含在范围内

@Test
    void notIn() {
        LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        ArrayList<Integer> arrayList = new ArrayList<>();
        Collections.addAll(arrayList, 18, 20, 21);
        lambdaQueryWrapper.notIn(User::getAge, arrayList);
        List<User> users = userMapper.selectList(lambdaQueryWrapper);
        System.out.println(users);
    }

【MybatisPlus快速入门】—— 进阶入门

3️⃣ inSql 包含在范围内(自己拼接SQL的形式)

  • 通过自己拼接SQL的方式来完成包含查询
    • 字节写个字符串充当集合,多个元素用逗号分隔开
    • 也可以通过 inSql 实现嵌套查询,将一个查询结果作为另一个查询条件
@Test
    void inSql() {
        LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.inSql(User::getAge, "18, 20, 22");
        List<User> users = userMapper.selectList(lambdaQueryWrapper);
        System.out.println(users);
    }

【MybatisPlus快速入门】—— 进阶入门

@Test
    void inSql2() {
        LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.inSql(User::getAge, "select age from user where age > 20");
        List<User> users = userMapper.selectList(lambdaQueryWrapper);
        System.out.println(users);
    }

【MybatisPlus快速入门】—— 进阶入门

4️⃣ notInSql 不包含在范围内(自己拼接SQL的形式)

@Test
    void notInSql() {
        LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.notInSql(User::getAge, "18, 20, 22");
        List<User> users = userMapper.selectList(lambdaQueryWrapper);
        System.out.println(users);
    }

【MybatisPlus快速入门】—— 进阶入门

@Test
    void notInSql2() {
        LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.notInSql(User::getAge, "select age from user where age > 20");
        List<User> users = userMapper.selectList(lambdaQueryWrapper);
        System.out.println(users);
    }

【MybatisPlus快速入门】—— 进阶入门

1.3.6 分组查询

1️⃣ groupBy 按指定字段分组

@Test
    void groupBy() {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        //分组字段,我们通过groupBy方法指定按哪个字段分组
        queryWrapper.groupBy("age");
        //查询字段,我们要查询出来哪些数据
        queryWrapper.select("age", "count(*) as field_count");
        List<Map<String, Object>> maps = userMapper.selectMaps(queryWrapper);
        System.out.println(maps);
    }

【MybatisPlus快速入门】—— 进阶入门

1.3.7 聚合查询

  • 在分组查询的基础上,通过 having 来实现聚合查询
    【MybatisPlus快速入门】—— 进阶入门
@Test
    void having() {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        //分组字段
        queryWrapper.groupBy("age");
        //查询字段
        queryWrapper.select("age", "count(*) as field_count");
        //聚合筛选
        queryWrapper.having("field_count >= 2");
        List<Map<String, Object>> maps = userMapper.selectMaps(queryWrapper);
        System.out.println(maps);
    }

【MybatisPlus快速入门】—— 进阶入门

1.3.8 排序查询

1️⃣ orderByAsc 升序查询

@Test
    void orderByAsc() {
        LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.orderByAsc(User::getAge, User::getId);
        List<User> users = userMapper.selectList(lambdaQueryWrapper);
        System.out.println(users);
    }

【MybatisPlus快速入门】—— 进阶入门

2️⃣ orderByDesc 降序查询

@Test
    void orderByDesc() {
        LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.orderByDesc(User::getAge, User::getId);
        List<User> users = userMapper.selectList(lambdaQueryWrapper);
        System.out.println(users);
    }

【MybatisPlus快速入门】—— 进阶入门

3️⃣ orderBy 可同时指定升序降序查询

  • 自己定制实现根据某些字段做升序、某些字段做降序排序
    • 多次调用 orderBy 方法
    • 第一个参数代表 如果字段值为空,是否还参与排序
    • 第二个参数代表 是否为升序排序
    • 第三个参数代表 我们选择排序的字段
@Test
    void orderBy(){
        LambdaQueryWrapper<User> userLambdaQueryWrapper = new LambdaQueryWrapper<>();
        userLambdaQueryWrapper.orderBy(false, true, User::getAge);
        userLambdaQueryWrapper.orderBy(true, false, User::getId);
        List<User> users = userMapper.selectList(userLambdaQueryWrapper);
        System.out.println(users);
    }

【MybatisPlus快速入门】—— 进阶入门

  • 有一个需要注意的地方:说明我们将orderBy的第一个条件设置为 false,那么只要查询范围内有一条数据的age为空,那么就会导致 age 这个字段不参与排序

【MybatisPlus快速入门】—— 进阶入门

1.3.9 func查询

  • 根据不同的业务情况来封装查询条件:【此处为了演示效果直接指定了boolean的类型】
    • 就是不同条件下我们的查询内容是不同的

1️⃣ 使用匿名内部类的形式 【可以简化为 Lambda 表达式的形式】

【MybatisPlus快速入门】—— 进阶入门
【MybatisPlus快速入门】—— 进阶入门
2️⃣ 下面为简化为Lambda表达式的形式

  • 在上面的代码按 Alt + Enter 就会提示我们进行转换

【MybatisPlus快速入门】—— 进阶入门

@Test
    void func(){
        LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.func(userLambdaQueryWrapper -> {
            if(true){
                lambdaQueryWrapper.eq(User::getId, 1);
            }else {
                lambdaQueryWrapper.ne(User::getId, 1);
            }
        });
        List<User> users = userMapper.selectList(lambdaQueryWrapper);
        System.out.println(users);
    }
  • 引申知识点:
    • 什么情况下, Java匿名内部类可以简化为Lambda表达式形式
      【MybatisPlus快速入门】—— 进阶入门
    • 接口中的方法不都是抽象方法吗?
      【MybatisPlus快速入门】—— 进阶入门

1.3.10 逻辑查询

1️⃣ and 与查询

  • 我们通过链式调用,默认就是与查询
@Test
    void and(){
        LambdaQueryWrapper<User> userLambdaQueryWrapper = new LambdaQueryWrapper<>();
        userLambdaQueryWrapper.gt(User::getAge, 18).lt(User::getAge, 22);
        List<User> users = userMapper.selectList(userLambdaQueryWrapper);
        System.out.println(users);
    }

【MybatisPlus快速入门】—— 进阶入门

  • 也可以采用嵌套的方式实现与查询
    【MybatisPlus快速入门】—— 进阶入门
@Test
    void and2(){
        LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(User::getName, "jack").and(i -> i.gt(User::getAge, 26).or().lt(User::getAge, 22));
        List<User> users = userMapper.selectList(lambdaQueryWrapper);
        System.out.println(users);
    }

【MybatisPlus快速入门】—— 进阶入门

2️⃣ or 或查询

  • 链式查询直接点调用 or() 代表或查询
@Test
    void or(){
        LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.lt(User::getAge, 20).or().gt(User::getAge, 22);
        List<User> users = userMapper.selectList(lambdaQueryWrapper);
        System.out.println(users);
    }

【MybatisPlus快速入门】—— 进阶入门

  • 当然我们的或查询也支持嵌套调用
    • 我们需要注意,是先完成内部查询再完成外部查询(先满足最内层的查询条件进行筛选)
@Test
    void or2(){
        LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(User::getName, "Jack").or(i -> i.gt(User::getAge, 22).lt(User::getAge, 26));
        //IDEA中通过 Ctrl + Alt + V 可以快速生成变量名
        List<User> users = userMapper.selectList(lambdaQueryWrapper);
        System.out.println(users);
    }

【MybatisPlus快速入门】—— 进阶入门

3️⃣ nested 快速构建查询

【MybatisPlus快速入门】—— 进阶入门

@Test
    void nested(){
        LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.nested(i -> i.eq(User::getName, "Tom").gt(User::getAge, 18));
        List<User> users = userMapper.selectList(lambdaQueryWrapper);
        System.out.println(users);
    }

【MybatisPlus快速入门】—— 进阶入门

1.3.11 自定义条件查询

  • 通过 apply 方法可以实现自定义查询
@Test
    void apply(){
        LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        //会将这部分的内容拼接到SQL的where后面
        lambdaQueryWrapper.apply("id = 1");
        List<User> users = userMapper.selectList(lambdaQueryWrapper);
        System.out.println(users);
    }

【MybatisPlus快速入门】—— 进阶入门

1.3.12 last查询

  • 通过last查询可以将我们指定的查询条件拼接到我们sql语句的最后【可以实现简单的分页查询】
@Test
    void last(){
        LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        //limit用于分页,两个参数代表从第几条开始获得几条数据
        lambdaQueryWrapper.last("limit 0, 2");
        List<User> users = userMapper.selectList(lambdaQueryWrapper);
        System.out.println(users);
    }

【MybatisPlus快速入门】—— 进阶入门

1.3.13 exists查询

1️⃣ exists 存在查询

  • 就是根据子查询语句的结果来选择主查询的结果是否保留
@Test
    void exists(){
        LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.exists("select id from user where age = 18");
        List<User> users = userMapper.selectList(lambdaQueryWrapper);
        System.out.println(users);
    }

【MybatisPlus快速入门】—— 进阶入门

2️⃣ notExists 不存在查询

  • notExists 的作用是子查询有数据–主查询不保留,子查询没数据–主查询保留
@Test
    void notExists(){
        LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.notExists("select id from user where age = 18");
        List<User> users = userMapper.selectList(lambdaQueryWrapper);
        System.out.println(users);
    }

【MybatisPlus快速入门】—— 进阶入门

1.3.14 字段查询

  • 通过 select 方法指定我们要查询哪些字段
@Test
    void select(){
        LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.select(User::getId, User::getName);
        List<User> users = userMapper.selectList(lambdaQueryWrapper);
        System.out.println(users);
    }

【MybatisPlus快速入门】—— 进阶入门


高阶篇

2.1 主键策略

2.1.1 主键生成策略介绍

  • 首先大家先要知道什么是主键,主键的作用就是唯一标识,我们可以通过这个唯一标识来定位到这条数据。
  • 当然对于表数据中的主键,我们可以自己设计生成规则,生成主键。
  • 在MybatisPlus中提供了一个注解 @TableId,该注解提供了各种的主键生成策略,我们可以通过使用该注解来对于新增的数据指定主键生成策略
  • 那么在以后新增数据的时候,数据就会按照我们指定的主键生成策略来生成对应的主键。

2.1.2 AUTO策略

  • 该策略为跟随数据库表的主键递增策略,前提是数据库表的主键要设置为自增

【MybatisPlus快速入门】—— 进阶入门

  • 实体类添加注解,指定主键生成策略

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class User {
        @TableId(type = IdType.AUTO)
        private Long id;
        private String name;
        private Integer age;
        private String email;
    }
    
  • 测试程序:

    @Test
    void primaryKey(){
        User user = new User();
        user.setName("Mary");
        user.setAge(35);
        user.setEmail("test7@powernode.com");
        userMapper.insert(user);
    }
    
  • 拼接的SQL语句如下
    【MybatisPlus快速入门】—— 进阶入门

2.1.3 INPUT策略

  • 该策略表示,必须由我们手动的插入id,否则无法添加数据

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class User {
        @TableId(type = IdType.INPUT)
        private Long id;
        private String name;
        private Integer age;
        private String email;
    }
    
  • 由于我们不使用AUTO了,所以把自动递增去掉
    【MybatisPlus快速入门】—— 进阶入门

  • 这里如果我们省略不写id,会发现,无法插入数据

    @Test
    void primaryKey(){
        User user = new User();
        user.setName("Jerry");
        user.setAge(38);
        user.setEmail("test8@powernode.com");
        userMapper.insert(user);
    }
    

【MybatisPlus快速入门】—— 进阶入门

  • 但是我们自己指定了id,发现可以添加成功
    @Test
    void primaryKey(){
        User user = new User();
        user.setId(8L);
        user.setName("Jerry");
        user.setAge(38);
        user.setEmail("test8@powernode.com");
        userMapper.insert(user);
    }
    

2.1.4 ASSIGN_ID策略

  • 如果我们将来一张表的数据量很大,我们需要进行分表。

  • 常见的分表策略有两种:

    • 水平拆分: 就是将一个大的表按照数据量进行拆分
      【MybatisPlus快速入门】—— 进阶入门

    • 垂直拆分: 垂直拆分就是将一个大的表按照字段进行拆分
      【MybatisPlus快速入门】—— 进阶入门

  • 其实我们对于拆分后的数据,有三点需求,就拿水平拆分来说:

    • 之前的表的主键是有序的,拆分后还是有序的
    • 虽然做了表的拆分,但是每条数据还需要保证主键的唯一性
    • 主键最好不要直接暴露数据的数量,这样容易被外界知道关键信息
  • 那就需要有一种算法,能够实现这三个需求,这个算法就是雪花算法

  • 雪花算法是由一个64位的二进制组成的,最终就是一个Long类型的数值, 主要分为四部分存储【转为十进制是19位】

    • 1位的符号位,固定值为0
    • 41位的时间戳
    • 10位的机器码,包含5位机器id和5位服务id
    • 12位的序列号

【MybatisPlus快速入门】—— 进阶入门

  • 使用雪花算法可以实现有序、唯一、且不直接暴露排序的数字
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    @TableId(type = IdType.ASSIGN_ID)
    private Long id;
    private String name;
    private Integer age;
    private String email;
}
@Test
void primaryKey(){
    User user = new User();
    user.setName("Jerry");
    user.setAge(38);
    user.setEmail("test8@powernode.com");
    userMapper.insert(user);
}

我们可以在插入后发现一个19位长度的id,该id就是雪花算法生成的id,这是二级制的十进制表示形式
【MybatisPlus快速入门】—— 进阶入门

2.1.5 NONE策略

  • NONE策略表示不指定主键生成策略,当我们没有指定主键生成策略或者主键策略为NONE的时候,他跟随的是全局策略
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    @TableId(type = IdType.NONE)
    private Long id;
    private String name;
    private Integer age;
    private String email;
}

那我们来看一下他的全局策略默认是什么,全局配置中 id-type是用于配置主键生成策略的,我们可以看一下id-type的默认值
【MybatisPlus快速入门】—— 进阶入门

通过查看源码发现,id-type的默认值就是雪花算法
【MybatisPlus快速入门】—— 进阶入门

2.1.6 ASSIGN_UUID策略

  • UUID(Universally Unique Identifier)全局唯一标识符,定义为一个字符串主键,采用32位数字组成,编码采用16进制,定义了在时间和空间都完全唯一的系统信息。

  • UUID的编码规则:

    • 1~8位采用系统时间,在系统时间上精确到毫秒级保证时间上的唯一性;
    • 9~16位采用底层的IP地址,在服务器集群中的唯一性;
    • 17~24位采用当前对象的HashCode值,在一个内部对象上的唯一性;
    • 25~32位采用调用方法的一个随机数,在一个对象内的毫秒级的唯一性。
  • 通过以上4种策略可以保证唯一性,在系统中需要用到随机数的地方都可以考虑采用UUID算法。

  • 我们想要演示UUID的效果,需要改变一下表的字段类型和实体类的属性类型

    • 将数据库表的字段类型改为varchar(50)
      【MybatisPlus快速入门】—— 进阶入门

将实体类的属性类型改为String,并指定主键生成策略为 IdType.ASSIGN_UUID

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    @TableId(type = IdType.ASSIGN_UUID)
    private String id;
    private String name;
    private Integer age;
    private String email;
}

完成数据的添加

@Test
void primaryKey(){
    User user = new User();
    user.setName("Jerry");
    user.setAge(38);
    user.setEmail("test8@powernode.com");
    userMapper.insert(user);
}

我们会发现,成功添加了一条数据,id为uuid类型
【MybatisPlus快速入门】—— 进阶入门

小结: 本章节讲解了主键生成策略,我们可以通过指定主键生成策略来生成不同的主键id,从而达到对于数据进行唯一标识的作用。

2.2 分页

  • 分页操作在实际开发中非常的常见,我们在各种平台和网站中都可以看到分页的效果

    • 例如:京东商城的分页效果
      【MybatisPlus快速入门】—— 进阶入门

    • 例如:百度的分页效果
      【MybatisPlus快速入门】—— 进阶入门

  • 在MybatisPlus中的查询语句是怎么实现的,我们可以通过两种方式实现查询语句

    • 通过MybatisPlus提供的方法来实现条件查询
    • 通过自定义SQL语句的方式来实现查询
  • 接下来我们就来演示这两种分页方式如何实现

2.2.1 分页插件

  • 在大部分场景下,如果我们的SQL没有这么复杂,是可以直接通过MybatisPlus提供的方法来实现查询的,在这种情况下,我们可以通过配置分页插件来实现分页效果

  • 分页的本质就是需要设置一个拦截器,通过拦截器拦截了SQL,通过在SQL语句的结尾添加limit关键字,来实现分页的效果
    【MybatisPlus快速入门】—— 进阶入门

接下来看一下配置的步骤

1️⃣ 通过配置类来指定一个具体数据库的分页插件,因为不同的数据库的方言不同,具体生成的分页语句也会不同,这里为Mysql数据库

@Configuration
public class MybatisPlusConfig {
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return interceptor;
    }
}

2️⃣ 实现分页查询效果

@Test
    void page(){
        LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<User>();
        //当前页是第几页,每页包含多少条信息
        IPage<User> userPage = new Page<>(2, 3);
        //执行查询
        userMapper.selectPage(userPage, lambdaQueryWrapper);
        //获取分页查询信息
        System.out.println("数据总条数: " + userPage.getTotal());
        System.out.println("总页数: " + userPage.getPages());
        System.out.println("每页显示数: " + userPage.getSize());
        System.out.println("当前是第几页: " + userPage.getCurrent());
        System.out.println("当前页包含的信息: " + userPage.getRecords());

    }

【MybatisPlus快速入门】—— 进阶入门

2.2.2 自定义分页插件

在某些场景下,我们需要自定义SQL语句来进行查询,接下来我们来演示一下自定义SQL的分页操作

1️⃣ 在 UserMapper.xml 映射配置文件中提供查询语句

<?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.powernode.mapper.UserMapper">

     <select id="selectByName" resultType="com.powernode.domain.User">
        select * from powershop_user where name = #{name}
     </select>

</mapper>

2️⃣ 在Mapper接口中提供对应的方法,方法中将IPage对象作为参数传入

@Mapper
public interface UserMapper extends BaseMapper<User> {
       IPage<User> selectByName(IPage<User> page, String name);
}

3️⃣ 表数据为

【MybatisPlus快速入门】—— 进阶入门

4️⃣ 实现分页查询效果

@Test
    void page2(){
        IPage<User> userPage = new Page<>(1, 3);
        userMapper.selectByName(userPage, "Marry");

        System.out.println("当前页: " + userPage.getCurrent());
        System.out.println("每页显示条数: " + userPage.getSize());
        System.out.println("总页数: " + userPage.getPages());
        System.out.println("总条数: " + userPage.getTotal());
        System.out.println("分页数据: " + userPage.getRecords());
    }

【MybatisPlus快速入门】—— 进阶入门

小结: 这里我们学习了两种分页的配置方法,将来以后我们在进行条件查询的时候,可以使用分页的配置进行配置。

2.3 ActiveRecord模式

  • ActiveRecord(活动记录,简称AR),是一种领域模型模式,特点是一个模型类对应关系型数据库中的一个表,而模型类的一个实例对应表中的一行记录 【利用我们的实体类对象去操作数据库中的表】
  • ActiveRecord 一直广受解释型动态语言( PHP 、 Ruby 等)的喜爱,通过围绕一个数据对象进行CRUD操作
  • 而 Java 作为准静态(编译型)语言,对于 ActiveRecord 往往只能感叹其优雅,所以 MP 也在 AR 道路上进行了一定的探索,仅仅需要让实体类继承 Model 类且实现主键指定方法,即可开启 AR 之旅。

那么如何使用 ActiveRecord 模式呢?

1️⃣ 让实体类继承Model类

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User extends Model<User> {
    private Long id;
    private String name;
    private Integer age;
    private String email;
}
  • 我们可以看到,Model类中提供了一些增删改查方法,这样的话我们就可以直接使用实体类对象调用这些增删改查方法
  • 简化了操作的语法,但是他的底层依然是需要UserMapper的,所以持久层接口并不能省略

测试ActiveRecord模式的增删改查

1️⃣ 添加操作

@Test
    void activeRecordAdd(){
        User user = new User();
        user.setName("LaoJiang");
        user.setAge(21);
        user.setEmail("LaoJiang@qq.com");
        user.insert();
    }

【MybatisPlus快速入门】—— 进阶入门

2️⃣ 删除操作

@Test
    void activeRecordDelete(){
        User user = new User();
        user.setId(1646343629209464834L);
        user.deleteById();
    }

【MybatisPlus快速入门】—— 进阶入门

3️⃣ 修改操作

@Test
    void activeRecordUpdate(){
        User user = new User();
        user.setId(1646342593128185857L);
        user.setName("雪花");
        user.updateById();
    }

【MybatisPlus快速入门】—— 进阶入门

4️⃣ 查询操作

@Test
    void activeRecordSelect(){
        User user = new User();
        user.setId(1L);
        user.selectById();
    }

【MybatisPlus快速入门】—— 进阶入门

2.3 SimpleQuery工具类

  • SimpleQuery可以对selectList查询后的结果用Stream流进行了一些封装,使其可以返回一些指定结果,简洁了api的调用

1️⃣ list

演示基于字段封装集合 【在查询的同时支持Stream流的操作】

@Test
    void testList(){
        List<Long> ids = SimpleQuery.list(new LambdaQueryWrapper<User>().eq(User::getName, "Marry"), User::getId);
        System.out.println(ids);
    }

【MybatisPlus快速入门】—— 进阶入门

演示对于封装后的字段进行lambda操作 【获取到的数据再加工,不会修改表中的数据】

@Test
    void testList2(){
        List<String> list = SimpleQuery.list(new LambdaQueryWrapper<User>().eq(User::getName, "Marry"), User::getName, user -> Optional.of(user.getName()).map(String::toLowerCase).ifPresent(user::setName));
        System.out.println(list);
    }

【MybatisPlus快速入门】—— 进阶入门

2️⃣ map

演示将所有的对象以id,实体的方式封装为Map集合

@Test
    void testMap(){
        Map<Long, User> map = SimpleQuery.keyMap(new LambdaQueryWrapper<User>(), User::getId);
        System.out.println(map);
    }

【MybatisPlus快速入门】—— 进阶入门

演示将单个对象以id,实体的方式封装为Map集合

@Test
    void testMap2(){
        //封装一条数据的Map集合
        Map<Long, User> map = SimpleQuery.keyMap(new LambdaQueryWrapper<User>().eq(User::getId, 2L), User::getId);
        System.out.println(map);
    }

【MybatisPlus快速入门】—— 进阶入门

演示只想要id和name组成的map

@Test
    void testMap3(){
        Map<Long, String> map = SimpleQuery.map(new LambdaQueryWrapper<User>(), User::getId, User::getName);
        System.out.println(map);
    }

【MybatisPlus快速入门】—— 进阶入门

3️⃣ Group

@Test
    void testGroup(){
        Map<String, List<User>> group = SimpleQuery.group(new LambdaQueryWrapper<User>(), User::getName);
        System.out.println(group);
    }

【MybatisPlus快速入门】—— 进阶入门

小结: 在这一小节,我们演示了SimpleQuery提供的Stream流式操作的方法,通过这些操作继续为我们提供了查询方面简化的功能文章来源地址https://www.toymoban.com/news/detail-421947.html

到了这里,关于【MybatisPlus快速入门】—— 进阶入门的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Blender纹理UV映射快速入门

    推荐:用 NSDT编辑器 快速搭建可编程3D场景 Blender 的功能包括 UV 映射,它是指将 3D 模型的表面展开到 2D 平面上并将纹理或图像应用到模型表面的过程。 这是创建具有真实纹理的 3D 模型的重要组成部分。 最新版本的 Blender (3.4) 包含有用的更新和功能,包括 UV 映射和 UV 编辑器

    2024年02月07日
    浏览(45)
  • DAY08_MyBatisPlus——入门案例&标准数据层开发CRUD-Lombok-分页功能&DQL编程控制&DML编程控制&乐观锁&快速开发-代码生成器

    问题导入 MyBatisPlus环境搭建的步骤? 1.1 SpringBoot整合MyBatisPlus入门程序 ①:创建新模块,选择Spring初始化,并配置模块相关基础信息 ②:选择当前模块需要使用的技术集(仅保留JDBC) ③:手动添加MyBatisPlus起步依赖 注意事项1:由于mp并未被收录到idea的系统内置配置,无法直

    2024年02月09日
    浏览(41)
  • 【node进阶】一文带你快速入门koa框架

    ✅ 作者简介:一名普通本科大三的学生,致力于提高前端开发能力 ✨ 个人主页:前端小白在前进的主页 🔥 系列专栏 : node.js学习专栏 ⭐️ 个人社区 : 个人交流社区 🍀 学习格言: ☀️ 打不倒你的会使你更强!☀️ 💯 刷题网站:这段时间有许多的小伙伴在问有没有什么

    2024年01月22日
    浏览(55)
  • 新鲜速递:Spring Data JPA 3.0快速入门、进阶到精通

    第一步,先确保你使用的是Spring Boot 3.0或以上环境,可以在pom.xml里加入Spring Data JPA依赖 第二步,配置你的Spring Data JPA,这里一定要有一个可以连接的数据库,这里以MySQL为例 至此安装完成 首先我们要知道Spring Data JPA的作用,Spring Data JPA是一种基于JPA技术的ORM框架封装,相当

    2023年04月08日
    浏览(45)
  • MybatisPlus基本使用(MP快速上手)

    目录 概述 MP快速上手(基本操作)  SpringBoot中MyBatisPlus环境搭建 增删改查 分页 条件查询(聚合,模糊,匹配范围) 条件:范围匹配 (大于小于等于...) 优化查询条件书写() 条件:查询投影 条件:模糊查询(非全文检索)  条件:聚合函数和分组 条件:排序操作   

    2024年02月05日
    浏览(29)
  • Gradio入门到进阶全网最详细教程[二]:快速搭建AI算法可视化部署演示(侧重参数详解和案例实践)

    相关文章:Gradio入门到进阶全网最详细教程[一]:快速搭建AI算法可视化部署演示(侧重项目搭建和案例分享) 在教程一中主要侧重讲解gradio的基础模块搭建以及demo展示,本篇文章则会侧重实际任务的搭建。 保持一贯作风简单展示一下如何使用 gradio的核心是它的gr.Interface函数,

    2023年04月26日
    浏览(51)
  • Gradio入门到进阶全网最详细教程[一]:快速搭建AI算法可视化部署演示(侧重项目搭建和案例分享)

    常用的两款AI可视化交互应用比较: Gradio Gradio的优势在于易用性,代码结构相比Streamlit简单,只需简单定义输入和输出接口即可快速构建简单的交互页面,更轻松部署模型。适合场景相对简单,想要快速部署应用的开发者。便于分享:gradio可以在启动应用时设置share=True参数

    2023年04月25日
    浏览(41)
  • MybatisPlus------MyBatisX插件:快速生成代码以及快速生成CRUD(十二)

    MyBatisX插件是IDEA插件,如果想要使用它,那么首先需要在IDEA中进行安装。 搜索\\\"MyBatisX\\\",点击Install,之后重启IDEA即可。 之后就可以在Mapper接口中,看到红色小鸟的标识,点击这个红色小鸟,会自动找到对应mapper.xml文件,以及文件中的方法。可以说十分方便。 在mapper.xml文件

    2024年02月04日
    浏览(42)
  • mybatisplus快速实现动态数据源切换

    1.背景   通常一个系统只需要连接一个数据库就可以了。但是在企业应用的开发中往往会和其他子系统交互,特别是对于一些数据实时性要求比较高的数据,我们就需要做实时连接查询,而不是做同步。这个时候就需要用到多数据源。   举个简单的例子某企业要做订单网上订

    2024年02月06日
    浏览(47)
  • dp专题14 爬楼梯(进阶)

    本题链接:题目页面 输入 输出 3         这是个 完全背包 + 排列数选取方法的dp问题。需要注意的是初始化 0 和 1 都为 1.

    2024年01月18日
    浏览(57)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包