• springboot+mybatis-plus初尝试


    MyBatis-Plus (opens new window)(简称 MP)是一个 MyBatis (opens new window)的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。
    在这里插入图片描述
    特性如下

    • 无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
    • 损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作,BaseMapper
    • 强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求,简单的CRUD操作不用自己编写。

    更多请查看官网。

    下面基于springboot,尝试这个MyBatis的增强工具,包括引入、配置、简单使用。
    1、创建springboot工程,引入mybatis-plus

    		
                com.baomidou
                mybatis-plus-boot-starter
                3.5.0
            
            
                com.baomidou
                dynamic-datasource-spring-boot-starter
                3.5.0
            
            
                mysql
                mysql-connector-java
                runtime
            
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    2、mysql数据库环境
    新建数据库
    在这里插入图片描述
    建议大家选择utf8mb4这种字符集,微信APP中微信用户名称的表情,是需要这种字符集才能存储的。
    新建表

    CREATE TABLE `user` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `nickname` varchar(255) NOT NULL COMMENT '昵称',
      `sex` tinyint(1) NOT NULL COMMENT '性别,1男2女',
      `create_time` datetime NOT NULL COMMENT '创建时间',
      `is_delete` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否删除 1是,0否',
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=50 DEFAULT CHARSET=utf8mb4;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    3、配置
    启动类添加mapper扫描注解

    @MapperScan("com.*.mapper")
    @SpringBootApplication
    public class SpringbootMybatisPlusApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(SpringbootMybatisPlusApplication.class, args);
        }
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    application.yml配置

    spring:
      datasource:
        dynamic:
          # 设置默认的数据源或者数据源组,默认值即为master
          primary: master
          # 严格匹配数据源,默认false. true未匹配到指定数据源时抛异常,false使用默认数据源
          strict: false
          datasource:
            master:
              url: jdbc:mysql://127.0.0.1:3306/mybatis_plus?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone =Asia/Shanghai
              username: root
              password: root
            slave_1:
              url: jdbc:mysql://127.0.0.1:3306/mybatis_plus?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone =Asia/Shanghai
              username: root
              password: root
          # 连接池
          hikari:
            max-lifetime: 1800000
            connection-timeout: 5000
            idle-timeout: 3600000
            max-pool-size: 12
            min-idle: 4
            connection-test-query: /**ping*/
    
    mybatis-plus:
      # 支持统配符 * 或者 ; 分割
      typeEnumsPackage: com.*.*.enums
    
    • 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

    这里面因为默认使用的是HikariCP数据源,目前也推荐使用这个,相比于druid有更高的性能,但是不能忽略下面的配置,否则服务会不断抛出异常,原因是数据库的连接时常和连接池的配置没有做好。
    3、使用
    实体类添加注解

    @TableName(value = "user")
    public class User {
    
        /**
         * 主键
         */
        @TableId(value = "id", type = IdType.AUTO)
        private Long id;
    
        /**
         * 昵称
         */
        @TableField("nickname")
        private String nickname;
    
        /**
         * 性别
         */
        @TableField(value = "sex")
        private SexEnum sex;
    
        /**
         * 版本
         */
        @TableField(value = "version",update = "%s+1")
        private Integer version;
    
        /**
         * 时间字段,自动添加
         */
        @TableField(value = "create_time",fill = FieldFill.INSERT)
        private LocalDateTime createTime;
    }
    
    • 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

    其中@TableName表名注解,用于标识实体类对应的表,其源码如下
    在这里插入图片描述
    @TableId主键注解,其源码如下
    在这里插入图片描述
    在这里插入图片描述
    AUTO:数据库自增 ID;
    NONE:该类型为未设置主键类型(注解里等于跟随全局,全局里约等于 INPUT);
    INPUT:用户自己设置的 ID;
    ASSIGN_ID:当用户传入为空时,自动分配类型为 Number 或 String 的主键(雪花算法);
    ASSIGN_UUID:当用户传入为空时,自动分配类型为 String 的主键;

    ASSIGN_ID默认采用的是雪花算法

    snowflake是Twitter开源的分布式ID生成算法,结果是一个long型的ID。其核心思想是:使用41bit作为毫秒数,10bit作为机器的ID(5个bit是数据中心,5个bit的机器ID),12bit作为毫秒内的流水号(意味着每个节点在每毫秒可以产生 4096 个 ID),最后还有一个符号位,永远是0。具体实现的代码可以参看https://github.com/twitter/snowflake。雪花算法支持的TPS可以达到419万左右(2^22*1000),几乎保证全球唯一。
    
    • 1

    @TableFiled字段注解,其源码如下
    在这里插入图片描述
    在这里插入图片描述
    持久层,mybatis-plus已经封装好了接口提供直接调用。

    @Mapper
    public interface UserMapper extends BaseMapper {
    }
    
    • 1
    • 2
    • 3

    业务层,也是mybatis-plus已经封装好了接口提供直接调用。

    public interface IUserService extends IService {
    }
    @Service
    public class UserServiceImpl extends ServiceImpl implements IUserService {
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    分页插件配置

    @Configuration
    @MapperScan("com.*.mapper*")
    public class MybatisPlusConfig {
    
        @Bean
        public MybatisPlusInterceptor mybatisPlusInterceptor() {
            MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
            interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
            return interceptor;
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    枚举配置
    相信后端的同学都经历过一个情况,比如性别这个字段,分别值和名称对应1男、2女,这个字段在数据库时是数值类型,而前端展示则是展示字符串的名称,传统解决方式如下

    • 数据库查询sql通过case判断,返回名称,以前oracle经常这么做;
    • 数据库返回的值,重新遍历赋值进去,这时候还需要判断这个值到底是男是女;
    • 前端写死,返回1就是男,返回2就是女;

    相信无论哪种方法都有其缺点,所以我们可以使用mybatis-plus提供的方式,在返回给前端时,只需要在遍历时get这个枚举,直接赋值其名称,不需要再次判断。

    @JsonFormat(shape = JsonFormat.Shape.OBJECT)
    public enum SexEnum implements IEnum {
    
        MAN(1, "男"),
        WOMAN(2, "女");
        private Integer code;
        private String name;
    
        SexEnum(Integer code, String name) {
            this.code = code;
            this.name = name;
        }
    
        @Override
        public Integer getValue() {
            return code;
        }
    
        public String getName() {
            return name;
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    其中,@JsonFormat注解为了解决枚举类返回前端只展示构造器名称的问题。
    配置文件扫描枚举

    mybatis-plus:
      # 支持统配符 * 或者 ; 分割
      typeEnumsPackage: com.ldc.*.enums
    
    • 1
    • 2
    • 3

    自动填充配置
    注解@TableFeild当中有个属性叫做fill,通过FieldFill设置属性,这个就是做自动填充用的。但是这个直接是不能使用的,需要通过实现mybatis-plus提供的接口,增加如下配置

    @Component
    public class MyMetaObjectHandler implements MetaObjectHandler {
    
        @Override
        public void insertFill(MetaObject metaObject) {
            // 起始版本 3.3.0(推荐使用)
            this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now());
        }
    
        @Override
        public void updateFill(MetaObject metaObject) {
            // 起始版本 3.3.0(推荐)
            this.strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    数据源配置
    配置文件当中配置了主从的方式,其实mybatis-plus还支持更多的方式,其使用方式为添加@DS注解,可以注解在方法上或类上,同时存在就近原则 【方法上注解】 优先于 【类上注解】

    @DS("slave_1")
    @Service
    public class UserServiceImpl extends ServiceImpl implements IUserService {
    
        @DS("salve_1")
        @Override
        public List getList() {
            return this.getList();
        }
    
        @DS("master")
        @Override
        public int saveUser(User user) {
            boolean save = this.save(user);
            if (save){
                return 1;
            }else{
                return 0;
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    sql日志配置

    mybatis-plus:
      # 支持统配符 * 或者 ; 分割
      typeEnumsPackage: com.ldc.*.enums
      configuration:
        log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    
    • 1
    • 2
    • 3
    • 4
    • 5

    结果类似如下
    在这里插入图片描述

    控制层

    	@Autowired
        private IUserService userService;
    
        /**
         * description: 新增
         * @return: boolean
         */
        @RequestMapping("/save")
        public boolean save() {
            User user = new User();
            user.setNickname("222");
            user.setSex(SexEnum.MAN);
            return userService.save(user);
        }
    
        /**
         * description: 修改
         * @param nickname
         * @param id
         * @return: boolean
         */
        @RequestMapping("/update")
        public boolean update(@RequestParam String nickname, @RequestParam Long id) {
            User user = new User();
            user.setNickname(nickname);
            user.setId(id);
            return userService.updateById(user);
        }
    
        /**
         * description: 删除
         * @param id
         * @return: boolean
         */
        @RequestMapping("/delete")
        public boolean delete(@RequestParam Long id) {
            User user = new User();
            user.setId(id);
            return userService.removeById(user);
        }
    
        /**
         * description: 列表
         */
        @RequestMapping("/list")
        public List list() {
            return userService.list();
        }
    
        /**
         * description: 分页列表
         * @param current
         * @param size
         */
        @RequestMapping("/page")
        public Page page(@RequestParam int current, @RequestParam int size) {
            return userService.page(new Page<>(current,size), new QueryWrapper(new User()));
        }
    
    • 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
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58

    还需在实际工程中应用,深入理解其能力和原理,加油吧,少年。

  • 相关阅读:
    逻辑漏洞(pikachu)
    python创建虚拟环境及相关配置(windows环境下)
    丹麦技术大学首创将量子计算应用于能源系统潮流建模
    水文-ts中对中文进行base64编码
    【多线程与高并发】从一则招聘信息进入多线程的世界
    【Python】这篇文章能让你明白经验模态分解(EMD)——EMD在python中的实现方法
    Gogs这款开源项目助你秒建Git服务!
    【K8S系列】Kubernetes的网络模型
    使用Windows系统自带的安全加密解密文件操作步骤详解
    简单的链接中心软件yal
  • 原文地址:https://blog.csdn.net/leijie0322/article/details/126311900