Mybatis-Plus简介

特性

  • 无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
  • 损耗小:启动即会自动注入基本 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 操作智能分析阻断,也可自定义拦截规则,预防误操作

支持数据库

  • MySQL,Oracle,DB2,H2,HSQL,SQLite,PostgreSQL,SQLServer,Phoenix,Gauss ,ClickHouse,Sybase,OceanBase,Firebird,Cubrid,Goldilocks,csiidb
  • 达梦数据库,虚谷数据库,人大金仓数据库,南大通用(华库)数据库,南大通用数据库,神通数据库,瀚高数据库

快速开始

  • 创建数据库表
    1. CREATE TABLE user
    2. (
    3. id BIGINT(20) NOT NULL COMMENT '主键ID',
    4. name VARCHAR(30) NULL DEFAULT NULL COMMENT '姓名',
    5. age INT(11) NULL DEFAULT NULL COMMENT '年龄',
    6. email VARCHAR(50) NULL DEFAULT NULL COMMENT '邮箱',
    7. PRIMARY KEY (id)
    8. );
  • 插入数据
    1. INSERT INTO user (id, name, age, email) VALUES
    2. (1, 'Jone', 18, 'test1@baomidou.com'),
    3. (2, 'Jack', 20, 'test2@baomidou.com'),
    4. (3, 'Tom', 28, 'test3@baomidou.com'),
    5. (4, 'Sandy', 21, 'test4@baomidou.com'),
    6. (5, 'Billie', 24, 'test5@baomidou.com');
  • 创建springboot项目,导入依赖,导入mybatis-plus-boot-starter后不需要导入 MyBatis以及 MyBatis-Spring,会有版本冲突 ```xml

    org.springframework.boot spring-boot-starter-web org.projectlombok lombok true org.springframework.boot spring-boot-starter-test test com.baomidou mybatis-plus-boot-starter 3.0.5 mysql mysql-connector-java junit junit test

  1. -
  2. 创建实体类
  3. ```java
  4. @Data
  5. @AllArgsConstructor
  6. @NoArgsConstructor
  7. public class User {
  8. private Long id;
  9. private String name;
  10. private Integer age;
  11. private String email;
  12. }
  • 创建mapper接口,继承BaseMapper,自动装配后可以直接使用基本方法 ```java @Repository public interface UserMapper extends BaseMapper {

}

  1. -
  2. 主启动类
  3. ```java
  4. @MapperScan("com.example.mybatisplusdemo.mapper")
  5. @SpringBootApplication
  6. public class MybatisPlusDemoApplication {
  7. public static void main(String[] args) {
  8. SpringApplication.run(MybatisPlusDemoApplication.class, args);
  9. }
  10. }
  • 测试:
    1. @Test
    2. public void testSelect() {
    3. System.out.println(("----- selectAll method test ------"));
    4. List<User> userList = userMapper.selectList(null);
    5. for (User user : userList) {
    6. System.out.println(user);
    7. }

日志配置

  1. mybatis-plus:
  2. configuration:
  3. log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

配置后即可在控制台查看日志

注解

@TableId

  • 描述:主键注解
  • 使用位置:实体类主键字段 | 属性 | 类型 | 必须指定 | 默认值 | 描述 | | :—- | :—- | :—- | :—- | :—- | | value | String | 否 | “” | 主键字段名 | | type | Enum | 否 | IdType.NONE | 指定主键类型 |

IdType

描述
AUTO 数据库 ID 自增
NONE 无状态,该类型为未设置主键类型(注解里等于跟随全局,全局里约等于 INPUT)
INPUT insert 前自行 set 主键值
ASSIGN_ID 分配 ID(主键类型为 Number(Long 和 Integer)或 String)(since 3.3.0),使用接口IdentifierGenerator的方法nextId(默认实现类为DefaultIdentifierGenerator雪花算法)
ASSIGN_UUID 分配 UUID,主键类型为 String(since 3.3.0),使用接口IdentifierGenerator的方法nextUUID(默认 default 方法)
ID_WORKER 分布式全局唯一 ID 长整型类型(please use ASSIGN_ID)
UUID 32 位 UUID 字符串(please use ASSIGN_UUID)
ID_WORKER_STR 分布式全局唯一 ID 字符串类型(please use ASSIGN_ID)
  1. @Documented
  2. @Retention(RetentionPolicy.RUNTIME)
  3. @Target({ElementType.FIELD})
  4. public @interface TableId {
  5. String value() default "";
  6. IdType type() default IdType.NONE;
  7. }

默认为IdType.NONE

主键生成策略

  • 测试
    1. @Test
    2. public void insertTest(){
    3. User user = new User();
    4. user.setName("霸哥");
    5. user.setAge(15);
    6. user.setEmail("1009703142@qq.com");
    7. userMapper.insert(user);
    8. System.out.println(user);
    9. }


此时显示的id为1489164848716582913,分布式系统全局唯一id生成,采用的是雪花算法

  • 修改主键生成策略为自增
    1. @Data
    2. @AllArgsConstructor
    3. @NoArgsConstructor
    4. public class User {
    5. @TableId(type = IdType.AUTO)
    6. private Long id;
    7. private String name;
    8. private Integer age;
    9. private String email;
    10. }


在数据库中自动生成的id为自增

@TableField

  • 描述:字段注解(非主键)

Mybatis-Plus - 图1

Mybatis-Plus - 图2

测试字段填充策略:

  • 数据库操作,添加字段
    Mybatis-Plus - 图3

  • 修改User属性 ```java // 插入时更新 @TableField(fill = FieldFill.INSERT) private Date createTime;

// 更新时更新 @TableField(fill = FieldFill.INSERT_UPDATE) private Date updateTime;

  1. -
  2. 创建handler实现MetaObjectHandler即可自动填充,注意要注入IOC
  3. ```java
  4. @Component
  5. public class MyMetaObjectHandler implements MetaObjectHandler {
  6. @Override
  7. public void insertFill(MetaObject metaObject) {
  8. this.setFieldValByName("createTime",new Date() ,metaObject);
  9. this.setFieldValByName("updateTime",new Date() ,metaObject);
  10. }
  11. @Override
  12. public void updateFill(MetaObject metaObject) {
  13. this.setFieldValByName("updateTime",new Date() ,metaObject);
  14. }
  15. }

@Version

乐观锁插件

OptimisticLockerInnerInterceptor

当要更新一条记录的时候,希望这条记录没有被别人更新
乐观锁实现方式:

  • 取出记录时,获取当前 version
  • 更新时,带上这个 version
  • 执行更新时, set version = newVersion where version = oldVersion
  • 如果 version 不对,就更新失败

测试

  • 添加字段,加上注解
    1. // 乐观锁字段注释
    2. @Version
    3. private Integer version;
  • 配置类,注册组件 ```java @EnableTransactionManagement @Configuration public class MybatisPlusConfig { /**
    • 旧版 */ @Bean public OptimisticLockerInterceptor optimisticLockerInterceptor() { return new OptimisticLockerInterceptor(); }

}

  1. <br />新版使用以下
  2. ```java
  3. @EnableTransactionManagement
  4. @Configuration
  5. public class MybatisPlusConfig {
  6. /**
  7. * 旧版
  8. */
  9. @Bean
  10. public OptimisticLockerInterceptor optimisticLockerInterceptor() {
  11. return new OptimisticLockerInterceptor();
  12. }
  13. }
  • 测试
    1. // 乐观锁测试,模拟多线程
    2. @Test
    3. public void updateOptimisticTest(){
    4. User user1 = userMapper.selectById(1L);
    5. user1.setName("霸哥");
    6. user1.setAge(15);
    7. user1.setEmail("1009703142@qq.com");
    8. User user2 = userMapper.selectById(1L);
    9. user2.setName("Bug");
    10. user1.setAge(18);
    11. user1.setEmail("1435345314@qq.com");
    12. userMapper.updateById(user2);
    13. userMapper.updateById(user1);
    14. }


字段只会更新user2的值。

@TableLogic

逻辑删除插件

  • 数据库中增加deleted字段,并在实体类字段上添加注解
    1. // 逻辑删除
    2. @TableLogic
    3. private Integer deleted;
  • 配置组件(新版不用配置)
    1. @Bean
    2. public ISqlInjector sqlInjector() {
    3. return new LogicSqlInjector();
    4. }
  • yml中设置删除设定的值,配置logic-delete-field可以不用加注解
    1. mybatis-plus:
    2. global-config:
    3. db-config:
    4. logic-delete-field: flag # 全局逻辑删除的实体字段名(since 3.3.0,配置后可以忽略不配置步骤2)
    5. logic-delete-value: 1 # 逻辑已删除值(默认为 1)
    6. logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
  • 测试 ```java @Test public void deleteTest() { userMapper.deleteById(1489164848716582917L); }

@Test public void selectTest() { userMapper.selectById(1489164848716582917L); }

  1. <br />此时删除变为更新deleted操作,查询会自动带上deleted=0条件。
  2. <a name="ba4ab757"></a>
  3. # 分页插件
  4. -
  5. 配置类中注册拦截器
  6. ```java
  7. //Spring boot方式
  8. @Configuration
  9. @MapperScan("com.baomidou.cloud.service.*.mapper*")
  10. public class MybatisPlusConfig {
  11. // 旧版
  12. @Bean
  13. public PaginationInterceptor paginationInterceptor() {
  14. PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
  15. // 设置请求的页面大于最大页后操作, true调回到首页,false 继续请求 默认false
  16. // paginationInterceptor.setOverflow(false);
  17. // 设置最大单页限制数量,默认 500 条,-1 不受限制
  18. // paginationInterceptor.setLimit(500);
  19. // 开启 count 的 join 优化,只针对部分 left join
  20. paginationInterceptor.setCountSqlParser(new JsqlParserCountOptimize(true));
  21. return paginationInterceptor;
  22. }
  23. // 最新版
  24. @Bean
  25. public MybatisPlusInterceptor mybatisPlusInterceptor() {
  26. MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
  27. interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.H2));
  28. return interceptor;
  29. }
  30. }
  • 测试:
    1. @Test
    2. public void pageTest() {
    3. Page<User> page = new Page(1 , 3);
    4. userMapper.selectPage(page, null);
    5. page.getRecords().forEach(System.out::println);
    6. // 获得总页数
    7. System.out.println(page.getTotal());
    8. }

代码生成器

AutoGenerator 是 MyBatis-Plus 的代码生成器,通过 AutoGenerator 可以快速生成 Entity、Mapper、Mapper XML、Service、Controller 等各个模块的代码,极大的提升了开发效率。

  • 引入依赖
    1. <dependency>
    2. <groupId>com.baomidou</groupId>
    3. <artifactId>mybatis-plus-generator</artifactId>
    4. <version>3.0.5</version>
    5. </dependency>
    6. <dependency>
    7. <groupId>org.apache.velocity</groupId>
    8. <artifactId>velocity-engine-core</artifactId>
    9. <version>2.3</version>
    10. </dependency>
  • 配置代码生成器类

    1. public class CodeGenerator {
    2. public static void main(String[] args) {
    3. // 我们需要构建一个代码生成器对象
    4. AutoGenerator mpg = new AutoGenerator();
    5. // 1、全局配置
    6. GlobalConfig gc = new GlobalConfig();
    7. String projectPath = System.getProperty("user.dir");//获取当前目录
    8. gc.setOutputDir(projectPath + "/src/main/java");//输出到哪个目录
    9. gc.setAuthor("peanut");
    10. gc.setOpen(false);//生成后是否打开文件夹位置
    11. gc.setFileOverride(false); // 是否覆盖
    12. gc.setServiceName("%sService");//去Service的I前缀
    13. gc.setIdType(IdType.ID_WORKER);
    14. gc.setDateType(DateType.ONLY_DATE);
    15. gc.setSwagger2(true);
    16. mpg.setGlobalConfig(gc);
    17. //2、设置数据源
    18. DataSourceConfig dsc = new DataSourceConfig();
    19. dsc.setUsername("root");
    20. dsc.setPassword("LJLljl20020728.+");
    21. dsc.setUrl("jdbc:mysql://localhost:3306/mybatis-plus?serverTimezone=UTC");
    22. dsc.setDriverName("com.mysql.cj.jdbc.Driver");
    23. dsc.setDbType(DbType.MYSQL);
    24. mpg.setDataSource(dsc);
    25. //3、包的配置
    26. PackageConfig pc = new PackageConfig();
    27. pc.setModuleName("user"); // 设置模块名
    28. pc.setParent("com.example"); // 设置父包名
    29. pc.setEntity("entity"); // 设置实体类包名
    30. pc.setMapper("mapper"); // 设置mapper接口类包名
    31. pc.setService("service"); // 设置service层包名
    32. pc.setController("controller"); // 设置controller层包名
    33. mpg.setPackageInfo(pc);
    34. //4、策略配置
    35. StrategyConfig strategy = new StrategyConfig();
    36. strategy.setInclude("user");// 设置要映射的表名,只需改这里即可
    37. strategy.setNaming(NamingStrategy.underline_to_camel);// 字段开启驼峰命名
    38. strategy.setColumnNaming(NamingStrategy.underline_to_camel);// 行开启驼峰命名
    39. strategy.setEntityLombokModel(true);// 是否使用lombok开启注解
    40. strategy.setLogicDeleteFieldName("deleted");
    41. //自动填充配置
    42. TableFill gmtCreate = new TableFill("gmt_create", FieldFill.INSERT);
    43. TableFill gmtUpdate = new TableFill("gmt_update", FieldFill.INSERT_UPDATE);
    44. ArrayList<TableFill> tableFills = new ArrayList<>();
    45. tableFills.add(gmtCreate);
    46. tableFills.add(gmtUpdate);
    47. strategy.setTableFillList(tableFills);
    48. //乐观锁配置
    49. strategy.setVersionFieldName("version");
    50. strategy.setRestControllerStyle(true);//开启驼峰命名
    51. strategy.setControllerMappingHyphenStyle(true);// 可映射风格localhost:8080/hello_id_2
    52. mpg.setStrategy(strategy);
    53. mpg.execute();//执行
    54. }
    55. }