• SpringBoot集成Mybatis-Plus


    简介

    MyBatis-Plus(简称 MP)是一个 MyBatis的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。

    因此,mybatis-plus包含mybatis的所有功能,因此无需再次引入mybatis。

    功能

    • 无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
    • 损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作
    • 强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求
    • 支持 Lambda 形式调用:通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错
    • 支持主键自动生成:支持多达 4 种主键策略(内含分布式唯一 ID 生成器 - Sequence),可自由配置,完美解决主键问题
    • 支持 ActiveRecord 模式:支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可进行强大的 CRUD 操作
    • 支持自定义全局通用操作:支持全局通用方法注入( Write once, use anywhere )
    • 内置代码生成器:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用
    • 内置分页插件:基于 MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通 List 查询
    • 分页插件支持多种数据库:支持 MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、Postgre、SQLServer 等多种数据库
    • 内置性能分析插件:可输出 Sql 语句以及其执行时间,建议开发测试时启用该功能,能快速揪出慢查询
    • 内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,也可自定义拦截规则,预防误操作

    MyBatis-plus 是一款 Mybatis 增强工具,用于简化开发,提高效率。下文使用缩写 mp来简化表示 MyBatis-plus,本文主要介绍 mp 搭配 Spring Boot 的使用。

    安装

    Maven Repository仓库官方最新依赖

    Maven

    1. <dependency>
    2. <groupId>com.baomidougroupId>
    3. <artifactId>mybatis-plus-boot-starterartifactId>
    4. <version>3.5.1version>
    5. dependency>

    Gradle

    1. compile group: 'com.baomidou', name: 'mybatis-plus-boot-starter', version: '3.5.1'

    快速开始

    官方文档推荐的快速集成文档,一共分为5步,分别为创建sql文件、添加pom依赖、配置jdbc连接、继承BaseMapper生成CRUD方法与测试使用。

    1.创建一个User表

    有一张 User 表,其表结构如下:

    创建对应的数据表 Schema 的表结构和表数据:

    schema_user.sql

    1. DROP TABLE IF EXISTS user;
    2. CREATE TABLE user
    3. (
    4. id BIGINT(20) NOT NULL COMMENT '主键ID',
    5. name VARCHAR(30) NULL DEFAULT NULL COMMENT '姓名',
    6. age INT(11) NULL DEFAULT NULL COMMENT '年龄',
    7. email VARCHAR(50) NULL DEFAULT NULL COMMENT '邮箱',
    8. PRIMARY KEY (id)
    9. );

    user_data.sql

    1. DELETE FROM user;
    2. INSERT INTO user (id, name, age, email) VALUES
    3. (1, 'Jone', 18, 'test1@baomidou.com'),
    4. (2, 'Jack', 20, 'test2@baomidou.com'),
    5. (3, 'Tom', 28, 'test3@baomidou.com'),
    6. (4, 'Sandy', 21, 'test4@baomidou.com'),
    7. (5, 'Billie', 24, 'test5@baomidou.com');

    2.添加Mybatis-Plus依赖

    引入 Spring Boot Starter 父工程:

    pom.xml

    1. <parent>
    2. <groupId>org.springframework.bootgroupId>
    3. <artifactId>spring-boot-starter-parentartifactId>
    4. <version>2.6.4version>
    5. <relativePath/>
    6. parent>
    7. <dependencies>
    8. <dependency>
    9. <groupId>org.springframework.bootgroupId>
    10. <artifactId>spring-boot-starterartifactId>
    11. dependency>
    12. <dependency>
    13. <groupId>com.baomidougroupId>
    14. <artifactId>mybatis-plus-boot-starterartifactId>
    15. <version>3.5.1version>
    16. dependency>
    17. <dependency>
    18. <groupId>mysqlgroupId>
    19. <artifactId>mysql-connector-javaartifactId>
    20. <scope>runtimescope>
    21. dependency>
    22. <dependency>
    23. <groupId>org.springframework.bootgroupId>
    24. <artifactId>spring-boot-configuration-processorartifactId>
    25. <optional>trueoptional>
    26. dependency>
    27. <dependency>
    28. <groupId>org.projectlombokgroupId>
    29. <artifactId>lombokartifactId>
    30. <optional>trueoptional>
    31. dependency>
    32. <dependency>
    33. <groupId>org.springframework.bootgroupId>
    34. <artifactId>spring-boot-starter-testartifactId>
    35. <scope>testscope>
    36. dependency>
    37. dependencies>

    3.配置数据库

    在 application.yml 配置文件中添加 H2 数据库的相关配置:

    1. server:
    2. port: 8080
    3. spring:
    4. datasource:
    5. driver-class-name: com.mysql.cj.jdbc.Driver
    6. url: jdbc:mysql://localhost:3306/springboot-in-action?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&useSSL=true
    7. username: root
    8. password: 123456

    在 Spring Boot 启动类中添加 @MapperScan 注解,扫描 Mapper 文件夹:

    1. @SpringBootApplication
    2. @MapperScan("com.deepinsea.springbootmybatisplus.mapper")
    3. public class Application {
    4. public static void main(String[] args) {
    5. SpringApplication.run(Application.class, args);
    6. }
    7. }

    4.创建一个实体类

    编写实体类 User.java(此处使用了 Lombok简化代码)

    1. @Data
    2. public class User {
    3. private Long id;
    4. private String name;
    5. private Integer age;
    6. private String email;
    7. }

    5.创建一个Mapper接口

    编写 Mapper 类 UserMapper.java

    1. public interface UserMapper extends BaseMapper<User> {
    2. }

    6.测试使用

    添加测试类,进行功能测试:

    1. @SpringBootTest
    2. public class SampleTest {
    3. @Autowired
    4. private UserMapper userMapper;
    5. @Test
    6. public void testSelect() {
    7. System.out.println(("----- selectAll method test ------"));
    8. List<User> userList = userMapper.selectList(null);
    9. Assert.assertEquals(5, userList.size());
    10. userList.forEach(System.out::println);
    11. }
    12. }

    UserMapper 中的 selectList() 方法的参数为 MP 内置的条件封装器 Wrapper,所以不填写就是无任何条件

    控制台输出:

    1. User(id=1, name=Jone, age=18, email=test1@baomidou.com)
    2. User(id=2, name=Jack, age=20, email=test2@baomidou.com)
    3. User(id=3, name=Tom, age=28, email=test3@baomidou.com)
    4. User(id=4, name=Sandy, age=21, email=test4@baomidou.com)
    5. User(id=5, name=Billie, age=24, email=test5@baomidou.com)

    小结

    通过以上几个简单的步骤,我们就实现了 User 表的 CRUD 功能,甚至连 XML 文件都不用编写!

    从以上步骤中,我们可以看到集成MyBatis-Plus非常的简单,只需要引入 starter 工程,并配置 mapper 扫描路径即可。

    插件使用

    1.自动生成主键

    实现原理:除了雪花id,其他自增和UUID算法都是在表ID本身设置了自增的情况下传递一个null值自动生成id,然后再使用mybatis-plus的id生成器生成的id替换数据库id(自增就不用替换了);而雪花算法,则是在内存中直接生成然后就设置为数据库id的值。

    在使用自动生成主键功能前,先设置数据id主键为自增ID,否则会导致主键id插入null错误(主键设置了不允许null的情况下)。

    两种id生成配置策略:1. 全局配置生成id类型;2. 局部表实体配置生成id类型。

    全局id生成策略

    1. mybatis-plus:
    2. global-config:
    3. db-config:
    4. #主键类型(auto:"自增id",assign_id:"全局唯一id(雪花算法,Long或者String类型)",assign_uuid:"全局唯一id(
    5. # 无中划线的uuid)",input:"自行设置id,默认null",none:"不设置主键id")
    6. id-type: assign_id

    局部id生成策略

    使用@TableId注解配置id生成类型

    user.java

    1. @EqualsAndHashCode(callSuper = false)
    2. @Data
    3. public class User extends Model {
    4. @TableId(type = IdType.AUTO)
    5. private Long id;
    6. @TableField(condition = SqlCondition.LIKE)
    7. private String name;
    8. @TableField(condition = "%s > #{%s}")
    9. private Integer age;
    10. private String email;
    11. private Long managerId;
    12. private LocalDateTime createTime;

    同时配置了这两种策略时,局部生成id类型配置优先级大于全局id生成类型配置。

    测试使用

    UserController.java

    1. /**
    2. * @Description 自动生成主键id(雪花算法)
    3. */
    4. @PostMapping("/add")
    5. public void addUser(){
    6. User user = new User();
    7. user.setName("testIdType");
    8. userMapper.insert(user);
    9. System.out.println("主键id为:" + user.getId());
    10. }

    注意的点

    • 局部字段的ID生成策略优先级高于全局的id生成策略
    • 使用雪花算法生成ID后,再次切换为主键自增的ID生成策略后会导致起始序列过大(没有重置起始序列值)
    • 另外如果原先指定了@TableId(type = IdType.AUTO),然后去除这部分代码,会发生Tuncate操作(即清空表并重置ID起始值)

    2.分页插件使用

    mybatis-plus分页插件旧版API为PaginationInterceptor,在3.5.1新版API为MybatisPlusInterceptor。

    mybatis-plus的分页插件也是内置的,无需添加其他依赖。

    旧版分页插件

    MybatisPlusPageConfig.java

    1. @Configuration
    2. public class MybatisPlusPageConfig {
    3. /**
    4. * 旧版本配置(已过时)
    5. */
    6. /*@Bean
    7. public PaginationInterceptor paginationInterceptor(){
    8. return new PaginationInterceptor();
    9. }*/
    10. /**
    11. * 新的分页插件(推荐)
    12. */
    13. @Bean
    14. public MybatisPlusInterceptor mybatisPlusInterceptor() {
    15. MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
    16. interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
    17. return interceptor;
    18. }
    19. }

    新版分页插件

    MybatisPlusConfig.java

    1. /**
    2. * Mybatis-plus配置类
    3. */
    4. @EnableTransactionManagement
    5. @Configuration
    6. @MapperScan(basePackages = "com.deepinsea.springbootmybatisplus.mapper")
    7. public class MybatisPlusConfig {
    8. /**
    9. * Mybatis-Plus 3.5.1新版分页插件API
    10. */
    11. @Bean
    12. public MybatisPlusInterceptor mybatisPlusInterceptor() {
    13. MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
    14. //乐观锁
    15. interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
    16. //分页锁
    17. interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
    18. return interceptor;
    19. }
    20. }

    测试使用

    UserController.java

    1. /**
    2. * @Description 内置分页插件的使用
    3. */
    4. @GetMapping("/page")
    5. public Page getByPage() {
    6. Page users = userMapper.selectPage(new Page<>(1, 2), null);
    7. System.out.println(users.getRecords());
    8. return users;
    9. }

    3.条件构造器使用

    mybatis-plus中有查询条件构造器QueryWrapper,可以在对常见的CRUD条件进行一些常见的构造,真实API在AbstractWrapper类中(采用了工厂模式进行顶层API设计)。

    可以封装sql对象,包括where条件,order by排序,select哪些字段等等 查询包装类,可以封装多数查询条件,泛型指定返回的实体类。

    测试使用

    SpringbootMybatisplusApplicationTests.java

    1. @Test
    2. public void testSelect() {
    3. System.out.println(("----- selectAll method test ------"));
    4. List userList = userMapper.selectList(null); # 查询全表数据
    5. userList.forEach(System.out::println);
    6. }

    UserController.java

    1. /**
    2. * @Description 条件构造器使用
    3. */
    4. @DeleteMapping("/delete")
    5. public void delUser(){
    6. // 1\. 根据ID删除
    7. // userMapper.deleteById(6);
    8. // userMapper.deleteBatchIds(Collections.singleton(7));
    9. // 2\. 根据map中的参数作为条件删除
    10. // Map map = new HashMap<>();
    11. // map.put("name", "testIdType");
    12. // map.put("id", 7);
    13. // userMapper.deleteByMap(map);
    14. // 3\. 条件构造器为参数的进行删除
    15. // ①普通条件构造器(注意不要添加<>,Entity转Object会报错)
    16. QueryWrapper wrapper = new QueryWrapper();
    17. wrapper.eq("id",6);
    18. userMapper.delete(wrapper);
    19. // ②lambda表达式条件构造器
    20. // LambdaQueryWrapper lambdaQuery = Wrappers.lambdaQuery();
    21. // lambdaQuery.eq(User::getId, 7).or().eq(User::getName, "testIdType");
    22. // userMapper.delete(lambdaQuery);
    23. }

    4.代码生成器使用

    引入依赖

    说明:freemarker是作为代码生成器的模板依赖,必须存在;而knife4j是兼容生成的代码带Swagger注释

    pom.xml

    1. <dependency>
    2. <groupId>com.baomidougroupId>
    3. <artifactId>mybatis-plus-generatorartifactId>
    4. <version>3.5.2version>
    5. dependency>
    6. <dependency>
    7. <groupId>org.freemarkergroupId>
    8. <artifactId>freemarkerartifactId>
    9. <version>2.3.31version>
    10. dependency>
    11. <dependency>
    12. <groupId>com.github.xiaoymingroupId>
    13. <artifactId>knife4j-spring-boot-starterartifactId>
    14. <version>2.0.7version>
    15. dependency>

    mybatis-plus 3.x版本

    SpringbootMybatisPlusApplication.java

    1. List<String> schemas = new ArrayList<>(); // 数据表列表
    2. schemas.add("user");
    3. FastAutoGenerator.create("jdbc:mysql://localhost:3306/springboot-in-action?serverTimezone=Asia/Shanghai",
    4. "root", "123456")
    5. //全局配置
    6. .globalConfig(builder -> {
    7. builder.author("deepinsea") // 设置作者
    8. .enableSwagger() // 开启 swagger 模式
    9. .fileOverride() // 覆盖已生成文件
    10. .disableOpenDir() // 禁止打开输出目录
    11. .dateType(DateType.TIME_PACK) // 时间策略
    12. .commentDate("yyyy-MM-dd") // 注释日期
    13. .outputDir(System.getProperty("user.dir")
    14. + "/src/main/java"); // 指定输出目录
    15. })
    16. //包配置
    17. .packageConfig(builder -> {
    18. builder.parent("generator") // 设置父包名(也可以生成目录)
    19. //.moduleName("system") // 设置父包模块名
    20. // .entity("model")
    21. // .service("service")
    22. // .controller("controller")
    23. // .mapper("mapper") // Mapper 包名
    24. // .xml("mapper") // Mapper XML 包名
    25. .pathInfo(Collections.singletonMap(
    26. OutputFile.xml,
    27. System.getProperty("user.dir")
    28. + "/src/main/resources/mapper")); // 设置mapperXml生成路径
    29. })
    30. //策略配置
    31. .strategyConfig(builder -> {
    32. builder.addInclude(schemas) // 设置需要生成的表名
    33. .addTablePrefix("") // 表前缀过滤
    34. .entityBuilder() // 切换至Entity设置
    35. .versionColumnName("version") // 乐观锁字段名(数据库)
    36. .logicDeleteColumnName("isDeleted") // 逻辑删除字段名(数据库)
    37. .enableLombok() // lombok生效
    38. .enableTableFieldAnnotation() // 所有实体类加注解
    39. .serviceBuilder() // 切换至Service层设置
    40. .formatServiceFileName("%sService") // 设定后缀名
    41. .formatServiceImplFileName("%sServiceImpl"); // 设定后缀名
    42. })
    43. //模板配置
    44. .templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker引擎模板,默认的是Velocity引擎模板
    45. .execute();

    测试使用

    点击运行项目即可后台静默在src主目录生成一个generate文件夹和resource目录生成一个mapper文件夹,代码文件都在这两个文件夹里

    注意:因为上面关闭了打开目录的开关,所以要看到文件目录生成,需要手动关闭项目才能刷新看到!

     

  • 相关阅读:
    2022-9-7合并k个已排序的链表---困难
    工程监测仪器无线振弦采集仪高低温试验箱测试原理
    【Python数据库】MongoDB
    Diffusion Models & CLIP
    FPGA 学习笔记:Vivado 2019.1 工程创建
    使用NRM管理Node镜像源,提升包下载速度
    2023年5个美国代理IP推荐,最佳代理花落谁家?
    学习笔记:机器学习之支持向量机(六、非线性支持向量机与核函数引入)
    linux系统调用拦截Centos7.6(三)の内核调用拦截
    Android流式布局
  • 原文地址:https://blog.csdn.net/LBWNB_Java/article/details/126340517