• mtbatisplus



    title: mybatis_plus
    date: 2023-09-03 21:06:27
    tags:


    mybatis_plusreviews

    约定大于配置

    默认

    当我们要使用mybatisplus的时候 我们需要去集成mp提供的BaseMapper

    public interface UserMapper extends BaseMapper

    关于mybatisplus常用注解

    注解到类上

    @TableName(“表名”) 用来解决 数据库表对应到java实体 符合驼峰命名

    注解到字段

    @TableId 默认是id为映射字段 可以自己指定 注意(一个实体对应一个表只有一个主键)

    mybatisplus不支持联合主键

    private Long id;

    1.0@TableField(“isMarried”)

    作用 解决实体属性与数据库字段不一致情况

    作用二、

    @TableField(“isMarried”)

    private Boolean isMarried 在对应到mybatisplus 查询语句时会自动去掉is 对应数据库 的Married字段

    作用三、

    @TableField(“order”)

    private Stringi order;

    实体名字与mysql的保留关键字冲突

    @exist()

    是否是数据库字段

    mybatisplus的配置可以替代mybatis的配置

    mybatis-plus:
    type-aliases-package: com.itheima.mp.domain.po
    global-config:
    db-config:
    id-type: *auto
    * logic-delete-field: deleted # *逻辑删除字段
    * configuration:
    default-enum-type-handler: com.baomidou.mybatisplus.core.handlers.MybatisEnumTypeHandler

    mybatis支持各种复杂的where条件

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    demo

       @Test
        public void test(){
            List<User> users = userMapper.queryUserByIds(List.of(1L, 2L, 3L));
            users.forEach(System.out::println);
        }
        @Test
        public void testdemo01(){
            //1.构建查询条件
            QueryWrapper<User> objectQueryWrapper = new QueryWrapper<User>()
                    .select("id", "username","info","balance")
                    .like("username","o")
                    .ge("balance",1000);
            List<User> users = userMapper.selectList(objectQueryWrapper);
            for (User user : users) {
                System.out.println(user.toString());
            }
        }
    
        @Test
        public void testqueryWrapper(){
            User user = new User();
            user.setBalance(2000);
            //1.构建查询条件
            QueryWrapper<User> objectQueryWrapper = new QueryWrapper<User>()
                    .eq("username","jack");
            userMapper.update(user,objectQueryWrapper);
        }
    
        @Test
        public void testUpdateWrapper(){
            UpdateWrapper<User> in = new UpdateWrapper<User>().setSql("balance=balance-200")
                    .in("id",List.of(1L, 2L, 4L));
            userMapper.update(null,in);
        }
        
        @Test
        public void testLamdaQueryWrapper(){
    
            //1.构建条件
            QueryWrapper<User> objectQueryWrapper = new QueryWrapper<>();
            LambdaQueryWrapper<User> userLambdaQueryWrapper = objectQueryWrapper.lambda().select(User::getId, User::getUsername, User::getBalance
                            , User::getInfo).like(User::getUsername, "0")
                    .ge(User::getBalance, 1000);
    
            List<User> users = userMapper.selectList(userLambdaQueryWrapper);
        }
    
    }
    
    
    • 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
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49

    lamdaQueryWrapper

    示例

    LambdaQueryWrapper userLambdaQueryWrapper = lamdQueryWrapper.lambda().select(User::getId, User::getUsername, User::getBalance
                            , User::getInfo).like(User::getUsername, "0")
                    .ge(User::getBalance, 1000);
    
    • 1
    • 2
    • 3

    自定义sql

    思想就是 我们where之后的判断条件采用mtbatis构建的并且采用${} 拼接到我们自己的

    示例

    首先定义一个queryWrapper传给自己的方法 也就是定义在mapper中的方法

    
        //定义条件
            QueryWrapper<User> objectQueryWrapper = new QueryWrapper<>();
                    objectQueryWrapper.lambda().in(User::getId,longs);
            //2.执行更新
            userMapper.updateBalanceByWrapper(200,objectQueryWrapper);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    mapper 注意mapper中只能用@Param(“ew”) 来接收自定义的条件 这是规定

     @Update("UPDATE user SET balance = balance - #{amount} ${ew.customSqlSegment}")
        void updateBalanceByWrapper(@Param("amount") int amount, @Param("ew") 							QueryWrapper<User> wrapper);
    
    • 1
    • 2
        该方法对应到Mapper.xml
       
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    因为mybatisplus没办法做多表查询 我们可以使用自定义sql来实现都多表查询

           List longs = List.of(1L, 2L, 3L);
            //定义条件
            QueryWrapper objectQueryWrapper = new QueryWrapper<>();
                new QueryWrapper().in("u.id",longs)
                        .eq("a.city","中国");
            //2.执行更新
            List users = userMapper.queryUsersByWrapper(objectQueryWrapper);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    xml文件

     
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    UPDATE user SET balance = balance - #{amount} ${ew.customSqlSegment}

        @Test
        public void testCustomSql(){
    
            List longs = List.of(1L, 2L, 3L);
    
            //定义条件
            QueryWrapper objectQueryWrapper = new QueryWrapper<>();
                    objectQueryWrapper.lambda().in(User::getId,longs);
            //2.执行更新
            userMapper.updateBalanceByWrapper(200,objectQueryWrapper);
    
    
        }
        
        在UserMapper接口
            @Update("UPDATE user SET balance = balance - #{amount} ${ew.customSqlSegment}")
        void updateBalanceByWrapper(@Param("amount") int amount, @Param("ew") QueryWrapper wrapper);
        
        
    
        @Test
        public void testJoinCustomSql(){
    
            List longs = List.of(1L, 2L, 3L);
    
            //定义条件
            QueryWrapper objectQueryWrapper = new QueryWrapper<>();
                new QueryWrapper().in("u.id",longs)
                        .eq("a.city","中国");
            //2.执行更新
            List users = userMapper.queryUsersByWrapper(objectQueryWrapper);
    
        }
        mapper接口
           List queryUsersByWrapper(@Param("ew") QueryWrapper wrapper);
           
           该方法对应到Mapper.xml
       
    
    • 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
    • 40
    • 41
    • 42
    • 43

    Service接口

    批处理记得开启mysql的 rewriteBatchedStatements=true 重写批处理方案 oracle默认开启

    如果不开启则是每次追加追加sql语句 即

    insetinto tablename values(?????)

    每次insert都是把我们的数据填充到问号中 而不是 直接拼接后values(1,2,3,4,5),(1,2,3,4,5)

    开启之后就是 values(1,2,3,4,5),(1,2,3,4,5)这种拼接 就是只执行一次sql

    url: jdbc:mysql://127.0.0.1:3306/mp?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true

    service层面 的lamdaQuery()

    示例 注意在service层面写的lamdaQuery()

    或者lamdaUpdate 条件的最后要追加执行的动作

    例如

    .one();

    .list();

    .update(); // 执行update

    userService.lambdaQuery().
    eq(User::getUsername,"jack")
    .one();
    
    • 1
    • 2
    • 3
       User user = userService.lambdaQuery()
                    .eq(User::getUsername, "Rose")
                    .one();
    
            System.out.println("user = " + user);
    
            List<User> list = userService.lambdaQuery()
                    .like(User::getUsername, "o")
                    .list();
            list.forEach(System.out::println);
    
            Long count = userService.lambdaQuery()
                    .like(User::getUsername, "o")
                    .count();
            System.out.println("count = " + count);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    动态sql查询示例

     return userService.lambdaQuery()
                    .like(username != null, User::getUsername, username)
                    .eq(status != null, User::getStatus, status)
                    .gt(min != null, User::getBalance, min)
                    .lt(max != null, User::getBalance, max)
                    .list();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
            userService.lambdaUpdate()
                    .set(User::getBalance, balance)
                    .set(balance == 0, User::getStatus, 2)
                    .eq(id != null, User::getId, id)
                    .eq(username != null, User::getUsername, username)
                    .update(); // 执行update
        
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    问题 为了解决循环依赖问题 mybatisplus 提供了静态工具类 DB

    循环依赖

    举例

    usersevice 需要adreeservice

    adreevice又需要 uservice

    我们在userservice注入addressservice

    在addressvice 注入uservice 就会出现循环依赖问题

    DB 类

    Db.save(user);
       
    List list = Db.list(new QueryWrapper().like("username", "o"));
    
    User user = Db.lambdaQuery(User.class)
                    .eq(User::getUsername, "Rose")
                    .one();
                    
    Long count = Db.lambdaQuery(User.class)
                    .like(User::getUsername, "o")
                    .count();
    Db.lambdaQuery(User.class)
                    .like(username != null, User::getUsername, username)
                    .eq(status != null, User::getStatus, status)
                    .gt(min != null, User::getBalance, min)
                    .lt(max != null, User::getBalance, max)
                    .list();
    Db.lambdaUpdate(User.class)
                    .set(User::getBalance, balance)
                    .set(balance == 0, User::getStatus, 2)
                    .eq(id != null, User::getId, id)
                    .eq(username != null, User::getUsername, username)
                    .update(); // 执行update
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    mybatisplus设置逻辑删除字段

    mybatis会自动检测我们的删除字段

    在我们执行删除操作的时候会替代成逻辑删除

    mybatis-plus:
      type-aliases-package: com.itheima.mp.domain.po
      global-config:
        db-config:
          id-type: auto
          logic-delete-field: deleted # 逻辑删除字段
      configuration:
        default-enum-type-handler: com.baomidou.mybatisplus.core.handlers.MybatisEnumTypeHandler
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    枚举转换器 JSON处理器 不实用

    需要配置mybatis的配置设置一个美剧转换器

    并且在枚举类加上注解

    ​ @EnumValue

    @Getter
    public enum UserStatus {
        NORMAL(1, "正常"),
        FREEZE(2, "冻结"),
        ;
        @EnumValue
        private final int value;
        @JsonValue
        private final String desc;
    
        UserStatus(int value, String desc) {
            this.value = value;
            this.desc = desc;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    configuration:
    default-enum-type-handler: com.baomidou.mybatisplus.core.handlers.MybatisEnumTypeHandler
    
    • 1
    • 2

    JSON

        @TableField(typeHandler = JacksonTypeHandler.class)
        private UserInfo info;
    
    
    • 1
    • 2
    • 3

    myabatisplus分页插件

    CV 大法好

    首先 mybatisplus的分页插件基于 mybatis的 interceptor

    先注册好核心拦截器 配置好mp的拦截器配置

        @Bean
        public MybatisPlusInterceptor mybatisPlusInterceptor(){
            // 1.创建核心拦截器
            MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
            // 2.创建插件
            PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor(DbType.MYSQL);
            paginationInnerInterceptor.setMaxLimit(1000L);
            interceptor.addInnerInterceptor(paginationInnerInterceptor);
            // 返回
            return interceptor;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    注意mybatis的分页插件条件时page对象

    返回的数据也是page对象

        @Test
        void testPageQuery() {
            int pageNo = 1, pageSize = 5;
            // 1.分页条件
            Page p = Page.of(pageNo, pageSize);
            // 2.排序条件
            p.addOrder(new OrderItem("balance", false));
    
            // 3.查询
            Page page = userService.page(p);
    
            // 4.分页结果
            long total = page.getTotal();
            System.out.println("total = " + total);
            long pages = page.getPages();
            System.out.println("pages = " + pages);
            List records = page.getRecords();
            for (User record : records) {
                System.out.println("record = " + record);
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    工具

    List users=p.getRecords();

    UserVO vo = BeanUtil.copyProperties(user, UserVO.class);

    加粗样式

  • 相关阅读:
    【Java】阿拉伯数字转汉字(完全符合中文阅读习惯)(支持所有整数类型)
    IT这个岗位,人才缺口百万,薪资水涨船高,上不封顶
    Linux系统运行时参数命令
    使用Egg调用mysql实现增删改查接口操作
    持续测试(Continuous Testing)
    这13个不经意却很不卫生的行为,很多人都没意识到
    Apache Solr9.3 快速上手
    呀!这款markdown编辑器我太中意啦!
    jdk对linux cgroup v2容器化环境识别情况
    数据库系统及应用复习——第九章关系查询处理和查询优化
  • 原文地址:https://blog.csdn.net/weixin_50635790/article/details/132702595