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
- 达梦数据库,虚谷数据库,人大金仓数据库,南大通用(华库)数据库,南大通用数据库,神通数据库,瀚高数据库
快速开始
- 创建数据库表
CREATE TABLE user(id BIGINT(20) NOT NULL COMMENT '主键ID',name VARCHAR(30) NULL DEFAULT NULL COMMENT '姓名',age INT(11) NULL DEFAULT NULL COMMENT '年龄',email VARCHAR(50) NULL DEFAULT NULL COMMENT '邮箱',PRIMARY KEY (id));
- 插入数据
INSERT INTO user (id, name, age, email) VALUES(1, 'Jone', 18, 'test1@baomidou.com'),(2, 'Jack', 20, 'test2@baomidou.com'),(3, 'Tom', 28, 'test3@baomidou.com'),(4, 'Sandy', 21, 'test4@baomidou.com'),(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
-创建实体类```java@Data@AllArgsConstructor@NoArgsConstructorpublic class User {private Long id;private String name;private Integer age;private String email;}
- 创建mapper接口,继承BaseMapper,自动装配后可以直接使用基本方法
```java
@Repository
public interface UserMapper extends BaseMapper
{
}
-主启动类```java@MapperScan("com.example.mybatisplusdemo.mapper")@SpringBootApplicationpublic class MybatisPlusDemoApplication {public static void main(String[] args) {SpringApplication.run(MybatisPlusDemoApplication.class, args);}}
- 测试:
@Testpublic void testSelect() {System.out.println(("----- selectAll method test ------"));List<User> userList = userMapper.selectList(null);for (User user : userList) {System.out.println(user);}
日志配置
mybatis-plus:configuration: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) |
@Documented@Retention(RetentionPolicy.RUNTIME)@Target({ElementType.FIELD})public @interface TableId {String value() default "";IdType type() default IdType.NONE;}
默认为IdType.NONE
主键生成策略
- 测试
@Testpublic void insertTest(){User user = new User();user.setName("霸哥");user.setAge(15);user.setEmail("1009703142@qq.com");userMapper.insert(user);System.out.println(user);}
此时显示的id为1489164848716582913,分布式系统全局唯一id生成,采用的是雪花算法
- 修改主键生成策略为自增
@Data@AllArgsConstructor@NoArgsConstructorpublic class User {@TableId(type = IdType.AUTO)private Long id;private String name;private Integer age;private String email;}
在数据库中自动生成的id为自增
@TableField
- 描述:字段注解(非主键)


测试字段填充策略:
数据库操作,添加字段

修改User属性 ```java // 插入时更新 @TableField(fill = FieldFill.INSERT) private Date createTime;
// 更新时更新 @TableField(fill = FieldFill.INSERT_UPDATE) private Date updateTime;
-创建handler实现MetaObjectHandler即可自动填充,注意要注入IOC中```java@Componentpublic class MyMetaObjectHandler implements MetaObjectHandler {@Overridepublic void insertFill(MetaObject metaObject) {this.setFieldValByName("createTime",new Date() ,metaObject);this.setFieldValByName("updateTime",new Date() ,metaObject);}@Overridepublic void updateFill(MetaObject metaObject) {this.setFieldValByName("updateTime",new Date() ,metaObject);}}
@Version
乐观锁插件
OptimisticLockerInnerInterceptor
当要更新一条记录的时候,希望这条记录没有被别人更新
乐观锁实现方式:
- 取出记录时,获取当前 version
- 更新时,带上这个 version
- 执行更新时, set version = newVersion where version = oldVersion
- 如果 version 不对,就更新失败
测试
- 添加字段,加上注解
// 乐观锁字段注释@Versionprivate Integer version;
- 配置类,注册组件
```java
@EnableTransactionManagement
@Configuration
public class MybatisPlusConfig {
/**
- 旧版 */ @Bean public OptimisticLockerInterceptor optimisticLockerInterceptor() { return new OptimisticLockerInterceptor(); }
}
<br />新版使用以下```java@EnableTransactionManagement@Configurationpublic class MybatisPlusConfig {/*** 旧版*/@Beanpublic OptimisticLockerInterceptor optimisticLockerInterceptor() {return new OptimisticLockerInterceptor();}}
- 测试
// 乐观锁测试,模拟多线程@Testpublic void updateOptimisticTest(){User user1 = userMapper.selectById(1L);user1.setName("霸哥");user1.setAge(15);user1.setEmail("1009703142@qq.com");User user2 = userMapper.selectById(1L);user2.setName("Bug");user1.setAge(18);user1.setEmail("1435345314@qq.com");userMapper.updateById(user2);userMapper.updateById(user1);}
字段只会更新user2的值。
@TableLogic
逻辑删除插件
- 数据库中增加deleted字段,并在实体类字段上添加注解
// 逻辑删除@TableLogicprivate Integer deleted;
- 配置组件(新版不用配置)
@Beanpublic ISqlInjector sqlInjector() {return new LogicSqlInjector();}
- yml中设置删除设定的值,配置logic-delete-field可以不用加注解
mybatis-plus:global-config:db-config:logic-delete-field: flag # 全局逻辑删除的实体字段名(since 3.3.0,配置后可以忽略不配置步骤2)logic-delete-value: 1 # 逻辑已删除值(默认为 1)logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
- 测试 ```java @Test public void deleteTest() { userMapper.deleteById(1489164848716582917L); }
@Test public void selectTest() { userMapper.selectById(1489164848716582917L); }
<br />此时删除变为更新deleted操作,查询会自动带上deleted=0条件。<a name="ba4ab757"></a># 分页插件-配置类中注册拦截器```java//Spring boot方式@Configuration@MapperScan("com.baomidou.cloud.service.*.mapper*")public class MybatisPlusConfig {// 旧版@Beanpublic PaginationInterceptor paginationInterceptor() {PaginationInterceptor paginationInterceptor = new PaginationInterceptor();// 设置请求的页面大于最大页后操作, true调回到首页,false 继续请求 默认false// paginationInterceptor.setOverflow(false);// 设置最大单页限制数量,默认 500 条,-1 不受限制// paginationInterceptor.setLimit(500);// 开启 count 的 join 优化,只针对部分 left joinpaginationInterceptor.setCountSqlParser(new JsqlParserCountOptimize(true));return paginationInterceptor;}// 最新版@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.H2));return interceptor;}}
- 测试:
@Testpublic void pageTest() {Page<User> page = new Page(1 , 3);userMapper.selectPage(page, null);page.getRecords().forEach(System.out::println);// 获得总页数System.out.println(page.getTotal());}
代码生成器
AutoGenerator 是 MyBatis-Plus 的代码生成器,通过 AutoGenerator 可以快速生成 Entity、Mapper、Mapper XML、Service、Controller 等各个模块的代码,极大的提升了开发效率。
- 引入依赖
<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-generator</artifactId><version>3.0.5</version></dependency><dependency><groupId>org.apache.velocity</groupId><artifactId>velocity-engine-core</artifactId><version>2.3</version></dependency>
配置代码生成器类
public class CodeGenerator {public static void main(String[] args) {// 我们需要构建一个代码生成器对象AutoGenerator mpg = new AutoGenerator();// 1、全局配置GlobalConfig gc = new GlobalConfig();String projectPath = System.getProperty("user.dir");//获取当前目录gc.setOutputDir(projectPath + "/src/main/java");//输出到哪个目录gc.setAuthor("peanut");gc.setOpen(false);//生成后是否打开文件夹位置gc.setFileOverride(false); // 是否覆盖gc.setServiceName("%sService");//去Service的I前缀gc.setIdType(IdType.ID_WORKER);gc.setDateType(DateType.ONLY_DATE);gc.setSwagger2(true);mpg.setGlobalConfig(gc);//2、设置数据源DataSourceConfig dsc = new DataSourceConfig();dsc.setUsername("root");dsc.setPassword("LJLljl20020728.+");dsc.setUrl("jdbc:mysql://localhost:3306/mybatis-plus?serverTimezone=UTC");dsc.setDriverName("com.mysql.cj.jdbc.Driver");dsc.setDbType(DbType.MYSQL);mpg.setDataSource(dsc);//3、包的配置PackageConfig pc = new PackageConfig();pc.setModuleName("user"); // 设置模块名pc.setParent("com.example"); // 设置父包名pc.setEntity("entity"); // 设置实体类包名pc.setMapper("mapper"); // 设置mapper接口类包名pc.setService("service"); // 设置service层包名pc.setController("controller"); // 设置controller层包名mpg.setPackageInfo(pc);//4、策略配置StrategyConfig strategy = new StrategyConfig();strategy.setInclude("user");// 设置要映射的表名,只需改这里即可strategy.setNaming(NamingStrategy.underline_to_camel);// 字段开启驼峰命名strategy.setColumnNaming(NamingStrategy.underline_to_camel);// 行开启驼峰命名strategy.setEntityLombokModel(true);// 是否使用lombok开启注解strategy.setLogicDeleteFieldName("deleted");//自动填充配置TableFill gmtCreate = new TableFill("gmt_create", FieldFill.INSERT);TableFill gmtUpdate = new TableFill("gmt_update", FieldFill.INSERT_UPDATE);ArrayList<TableFill> tableFills = new ArrayList<>();tableFills.add(gmtCreate);tableFills.add(gmtUpdate);strategy.setTableFillList(tableFills);//乐观锁配置strategy.setVersionFieldName("version");strategy.setRestControllerStyle(true);//开启驼峰命名strategy.setControllerMappingHyphenStyle(true);// 可映射风格localhost:8080/hello_id_2mpg.setStrategy(strategy);mpg.execute();//执行}}
