MyBatis-Plus

Reference:

1. MyBatisPlus简介

1.1 前言

Mybatis-Plus可以节省我们大量工作时间,所有的CRUD代码都可以自动化完成

  • 类似的工具

    • JPA
      • Java Persistence API(Java 持久层 API):用于对象持久化的 API
      • 作用:使得应用程序以统一的方式访问持久层
    • tk-mapper
  • 实体类实心可序列化接口

1.2 MyBatis-Plus

1.2.1 简介

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

image-20230808215938684

1.2.2 特性

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

2. 基本使用

使用第三方组件的步骤:

  1. 导入对应的依赖
  2. 研究依赖如何配置
  3. 代码如何编写
  4. 提高拓展技术能力

2.1 创建数据库

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
create database if not exists mybatis_plus;
use mybatis_plus;

-- 创建 `user` 表
DROP TABLE IF EXISTS user;
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)
);
-- 真实开发中,需要一些字段 version(乐观锁) deleted(逻辑删除) gmt_create gmt_modified(自动填充)

-- 插入数据
DELETE
FROM user;
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');

2.2 初始化SpringBoot项目

2.2.1 导入依赖

1
2
3
4
5
6
<!-- https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-boot-starter -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.3.1</version>
</dependency>

:warning: 引入 MyBatis-Plus 之后不要再次引入 MyBatisMyBatis-Spring,避免版本差异导致的问题

2.1.2 连接数据库

1
2
3
4
5
6
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: 123456
url: jdbc:mysql://localhost:3306/mybatis_plus?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=UTC

2.3 pojo-dao

  1. pojo
1
2
3
4
5
6
7
8
9
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
private int id;
private String name;
private int age;
private String email;
}
  1. dao
1
2
3
4
// 在对应的Mapper上面继承基本的类 BaseMapper
public interface UserMapper extends BaseMapper<User> {
// 此时,所有的CRUD操作都已经编写完成
}
  1. 扫描接口

主启动类添加注释,扫描dao包下的所有接口

  • 或者在 UserMapper 上增加 @Mapper 注释
1
@MapperScan("com.bayyy.dao")
  1. 测试
1
2
3
4
5
6
7
@Autowired
private UserMapper userMapper;

@Test
void contextLoads() {
userMapper.selectList(null).forEach(System.out::println);
}

image-20230809170952338

3. 配置日志

Mybatis-Plus 自动生成的 sql 语句是不可见的,需要查看日志查看相关细节

  • 一般开发环境中进行日志输出,项目发布后关闭日志
1
2
3
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

image-20230809171336813

4. CRUD扩展

4.1 Insert-插入

1
2
3
4
5
User user = new User();
user.setName("Bayyy");
user.setAge(20);
user.setEmail("110@011.com");
int result = userMapper.insert(user);
  • 测试结果:image-20230809171805216

4.2 update-更新

1
2
3
4
5
6
7
8
@Test
void testUpdate() {
User user = new User();
user.setId(1);
user.setName("Update");
userMapper.updateById(user);
System.out.println(user);
}

image-20230809173421885

  • 发发接收的是一个泛型,故参数需要给一个对象
  • 测试结果:image-20230809173343814

4.3 select-查询

4.3.1 单个查询

1
User user = userMapper.selectById(1);

4.3.2 批量查询

1
List<User> users = userMapper.selectBatchIds(Arrays.asList(1, 2, 3));

image-20230809213937613

4.3.3 条件查询

1
2
3
HashMap<String, Object> map = new HashMap<>();
map.put("name", "Bayyy");
List<User> userList = userMapper.selectByMap(map);

image-20230809214312458

4.4 删除操作

4.4.1 单个删除

1
2
// 根据id删除
userMapper.deleteById(1);

4.4.2 批量删除

1
2
// 根据id批量删除
userMapper.deleteBatchIds(Arrays.asList(1, 2));

**image-20230810134028108**

4.4.3 条件删除

1
2
3
4
5
// 条件删除
HashMap<String, Object> map = new HashMap<>();
map.put("name", "Bayyy");
map.put("id", 23);
userMapper.deleteByMap(map);

image-20230810134211277

4.4.4 逻辑删除

逻辑删除 | MyBatis-Plus

  • 物理删除:从数据库中直接移除

  • 逻辑删除:再数据库中没有被移除,而是通过一个变量来让它失效! deleted = 0 => deleted = 1

  • 说明:
    • 只对自动注入的sql起效:
    • 插入: 不作限制
    • 查找: 追加where条件过滤掉已删除数据,且使用 wrapper.entity 生成的where条件会忽略该字段
    • 更新: 追加where条件防止更新到已删除数据,且使用 wrapper.entity 生成的where条件会忽略该字段
    • 删除: 转变为 更新
  • 例如:
    • 删除: update user set deleted=1 where id = 1 and deleted=0
    • 查找: select id,name,deleted from user where deleted=0
  • 字段类型支持说明:
    • 支持所有数据类型(推荐使用 Integer,Boolean,LocalDateTime)
    • 如果数据库字段使用datetime,逻辑未删除值和已删除值支持配置为字符串null,另一个值支持置为函数来获取值如now()
  • 附录:
    • 逻辑删除是为了方便数据恢复和保护数据本身价值等等的一种方案,但实际就是删除。
      如果你需要频繁查出来看就不应使用逻辑删除,而是以一个状态去表示。
  1. 添加逻辑删除字段

image-20230810134630210

  1. pojo修改
1
2
3
// 逻辑删除
@TableLogic // 逻辑删除注解
private int deleted;
  1. 配置
1
2
3
4
5
6
mybatis-plus:
global-config:
db-config:
logic-delete-field: deleted # 全局逻辑删除的实体字段名(since 3.3.0,配置后可以忽略不配置步骤2)
logic-delete-value: 1 # 逻辑已删除值(默认为 1)
logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
  1. 删除测试
1
2
// 根据id删除
userMapper.deleteById(1);

image-20230810135216958

5. 基本插件功能

5.1 主键生成

5.1.1 主键生成策略

UUID、自增ID、雪花算法、redis、Zookeeper

  • 雪花算法
    • snowflake是Twitter开源的分布式ID生成算法,结果是一个long型的ID。
    • 核心思想:使用41bit作为毫秒数,10bit作为机器的ID(5个bit是数据中心,5个bit的机器ID),12bit作为毫秒内的流水号(意味着每个节点在每毫秒可以产生 4096 个 ID),最后还有一个符号位,永远是0。

5.1.2 主键自增

  • 实体类字段增加 @TableId
1
2
3
4
5
public class User {
@TableId(type = IdType.AUTO)
private int id;
...
}
  • 其余方法
1
2
3
4
5
6
7
public enum IdType {
AUTO(0), // 自增
NONE(1), // 无
INPUT(2), // 手动输入
ASSIGN_ID(3), // 分配ID
ASSIGN_UUID(4); // 分配UUID
}

5.2 自动填充

5.2.1 数据库级别的修改

  1. 表中新增字段 create_timeupdate_time

image-20230809205441678

  1. 测试插入和更新操作

image-20230809205502181

image-20230809205649241

5.2.2 代码级别

  1. 数据库其中的默认值等删除

  2. 实体类字段属性上需要增加注解

1
2
3
4
5
6
7
// 字段添加填充内容
// INSERT:插入时填充
@TableField(fill = FieldFill.INSERT)
private LocalDateTime createTime;
// UPDATE:更新时填充
@TableField(fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updateTime;
  1. 编写处理器对注解进行处理

Doucment:自动填充功能 | MyBatis-Plus

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Slf4j // 日志
@Component // 注册到容器中
public class MyMetaObjectHandler implements MetaObjectHandler {
// 插入时填充策略
@Override
public void insertFill(MetaObject metaObject) {
log.info("start insert fill...");

this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now());
this.strictInsertFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());
}

// 更新时填充策略
@Override
public void updateFill(MetaObject metaObject) {
log.info("start update fill...");
this.strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());
}
}
  • 测试结果:image-20230809211308468

5.3 乐观锁

5.3.1 简介

乐观锁 OptimisticLockerInnerInterceptor

  • 顾名思义十分乐观,它总是认为不会出现问题,无论干什么都不会上锁!如果出现问题就再次更新测试
  • 步骤:
    1. 取出记录时,获取当前version
    2. 更新时,带上这个version
    3. 执行更新时, set version = newVersion where version = oldVersion
    4. 如果version不对,就更新失败

5.3.2 测试

说明:

  • 支持的数据类型只有:int, Integer, long, Long, Date, Timestamp, LocalDateTime
  • 整数类型下 newVersion = oldVersion + 1
  • newVersion 会回写到 entity
  • 仅支持 updateById(id)update(entity, wrapper) 方法
  • update(entity, wrapper) 方法下, wrapper 不能复用!!!
  1. 数据库增加 version 字段

image-20230809211802420

  1. pojo增加对应字段
1
2
3
// 乐观锁
@Version
private int version;
  1. 注册组件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// Spring Boot 方式
@Configuration // 声明为配置类
@EnableTransactionManagement // 自动开启事务管理(默认就是开启的)
@MapperScan("com.bayyy.dao") // 扫描Mapper接口,按需修改即可
public class MybatisPlusConfig {
/**
* 旧版
*/
@Bean
public OptimisticLockerInterceptor optimisticLockerInterceptor() {
return new OptimisticLockerInterceptor();
}

/**
* 新版
*/
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
mybatisPlusInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
return mybatisPlusInterceptor;
}
}
  1. 测试

修改的用户不能为 new 出的新对象,必须为查询出来的结果

1
2
3
4
5
6
7
@Test
void testUpdate() {
User user = userMapper.selectById(1);
user.setName("Bayyy_version");
userMapper.updateById(user);
System.out.println(user);
}
  • 测试结果:image-20230809213257788

5.4 分页查询

  1. 注册组件

官网配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Configuration
@MapperScan("scan.your.mapper.package")
public class MybatisPlusConfig {

/**
* 新的分页插件,一缓和二缓遵循mybatis的规则,需要设置 MybatisConfiguration#useDeprecatedExecutor = false 避免缓存出现问题(该属性会在旧插件移除后一同移除)
*/
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.H2));
return interceptor;
}

@Bean
public ConfigurationCustomizer configurationCustomizer() {
return configuration -> configuration.setUseDeprecatedExecutor(false);
}
}

最新版中,所有配置都放在同一类下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
// 注册乐观锁插件
MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
mybatisPlusInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
/**
* 新的分页插件,一缓和二缓遵循mybatis的规则,需要设置 MybatisConfiguration#useDeprecatedExecutor = false 避免缓存出现问题(该属性会在旧插件移除后一同移除)
*/
// PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor(DbType.H2);
// paginationInnerInterceptor.setOverflow(true); // 设置溢出总页数后是否进行处理(default = false)
// paginationInnerInterceptor.setMaxLimit(500L); // 设置单页最大限制数量,默认 500 条,-1 不受限制
// paginationInnerInterceptor.setDbType(DbType.H2); // 设置数据库类型(default = H2)
// paginationInnerInterceptor.setDialect(new PostgreDialect()); // 设置方言类型(default = H2)

mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return mybatisPlusInterceptor;
}
  1. 测试

class Page()

  • 该类继承了 IPage 类,实现了 简单分页模型 如果要实现自己的分页模型,可以继承 Page 类或者实现 IPage
属性名 类型 默认值 描述
records List emptyList 查询数据列表
total Long 0 查询列表总记录数
size Long 10 每页显示条数,默认 10
current Long 1 当前页
orders List emptyList 排序字段信息,允许前端传入的时候,注意 SQL 注入问题,可以使用 SqlInjectionUtils.check(...) 检查文本
optimizeCountSql boolean true 自动优化 COUNT SQL 如果遇到 jSqlParser 无法解析情况,设置该参数为 false
optimizeJoinOfCountSql boolean true 自动优化 COUNT SQL 是否把 join 查询部分移除
searchCount boolean true 是否进行 count 查询,如果指向查询到列表不要查询总记录数,设置该参数为 false
maxLimit Long 单页分页条数限制
countId String xml 自定义 count 查询的 statementId 也可以不用指定在分页 statementId 后面加上 _mpCount 例如分页 selectPageById 指定 count 的查询 statementId 设置为 selectPageById_mpCount 即可默认找到该 SQL 执行
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public Page() {}

/**
* 分页构造函数
*
* @param current 当前页
* @param size 每页显示条数
* @param total 查询列表总记录数
* @param searchCount 是否进行 count 查询,如果指向查询到列表不要查询总记录数,设置该参数为 `false`
*/
public Page(long current, long size) {}
public Page(long current, long size, long total) {}
public Page(long current, long size, boolean searchCount) {}
public Page(long current, long size, long total, boolean searchCount) {}
1
2
3
4
5
6
7
@Test
void testPage() {
Page<User> page = new Page<>(1, 5);
userMapper.selectPage(page, null);
List<User> userList = page.getRecords();
userList.forEach(System.out::println);
}
  • 测试结果:image-20230810133331646

6. 性能分析-p6spy

  1. 导入依赖
1
2
3
4
5
6
<!-- https://mvnrepository.com/artifact/p6spy/p6spy -->
<dependency>
<groupId>p6spy</groupId>
<artifactId>p6spy</artifactId>
<version>3.9.1</version>
</dependency>
  1. springboot配置
1
2
3
4
5
6
spring:
datasource:
driver-class-name: com.p6spy.engine.spy.P6SpyDriver
url: jdbc:p6spy:mysql://localhost:3306/mybatis_plus?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=UTC
username: root
password: 123456
  1. spy配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#3.2.1以上使用
modulelist=com.baomidou.mybatisplus.extension.p6spy.MybatisPlusLogFactory,com.p6spy.engine.outage.P6OutageFactory
#3.2.1以下使用或者不配置
#modulelist=com.p6spy.engine.logging.P6LogFactory,com.p6spy.engine.outage.P6OutageFactory
# 自定义日志打印
logMessageFormat=com.baomidou.mybatisplus.extension.p6spy.P6SpyLogger
#日志输出到控制台
appender=com.baomidou.mybatisplus.extension.p6spy.StdoutLogger
# 使用日志系统记录 sql
#appender=com.p6spy.engine.spy.appender.Slf4JLogger
# 设置 p6spy driver 代理
deregisterdrivers=true
# 取消JDBC URL前缀
useprefix=true
# 配置记录 Log 例外,可去掉的结果集有error,info,batch,debug,statement,commit,rollback,result,resultset.
excludecategories=info,debug,result,commit,resultset
# 日期格式
dateformat=yyyy-MM-dd HH:mm:ss
# 实际驱动(可多个)
#driverlist=com.mysql.cj.jdbc.Driver
# 是否开启慢SQL记录
outagedetection=true
# 慢SQL记录标准 2 秒
outagedetectioninterval=2
  1. 测试

image-20230810142820150

7. 条件构造器-wrapper

条件构造器 | MyBatis-Plus

7.1 比较

  • 非空 isNotNull
  • isNull
  • 相等 eq
  • 不等于 ne
  • 大于 gt
  • 大于等于 ge
  • 小于 lt
  • 小于等于 le
  • 区间 between
1
2
3
4
5
6
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.ge("age", 20) // age >= 20
.lt("age", 100) // age < 100
.isNotNull("name") // name 非空
.isNull("email"); // email 为空
userMapper.selectList(wrapper).forEach(System.out::println);
  • 测试结果:image-20230810144230674

7.2 模糊查询

  • like - LIKE ‘%值%’
  • notLike - NOT LIKE ‘%值%’
  • likeLeft - LIKE ‘%值’
  • likeRight - LIKE ‘值%’
  • notLikeLeft - NOT LIKE ‘%值’
  • notLikeRight - NOT LIKE ‘值%’

  • in

    • in("age",{1,2,3})—->age in (1,2,3)
    • in("age", 1, 2, 3)—->age in (1,2,3)
  • notIn
1
2
3
4
5
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.likeLeft("age", 2) // age like "%2"
.in("name", new String[]{"Bayyy", "Bayyy2"}) // name in ("Bayyy", "Bayyy2")
.notIn("id", new Integer[]{1, 2, 3}); // id not in (1, 2, 3)
userMapper.selectList(wrapper).forEach(System.out::println);
  • 测试结果:image-20230810145913933

7.3 联表查询

  • inSql
    • inSql("age", "1,2,3,4,5,6")—->age in (1,2,3,4,5,6)
    • inSql("id", "select id from table where id < 3")—->id in (select id from table where id < 3)
  • notInSql
1
2
3
4
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.inSql("id", "select id from user where id < 30") // id in (select id from user where id < 30
.notInSql("age", "select age from user where age < 30 and age > 3"); // age not in (select age from user where age < 30 and age > 3)
userMapper.selectList(wrapper).forEach(System.out::println);
  • 测试结果:image-20230810150352574

7.4 分组/排序

  • groupBy - groupBy("id", "name")—->group by id,name

  • orderByAsc - orderByAsc("id", "name")—->order by id ASC,name ASC

  • orderByDesc - orderByDesc("id", "name")—->order by id DESC,name DESC
  • orderBy - orderBy(boolean condition, boolean isAsc, R... columns)

8. 代码自动生成器

代码生成器配置新 | MyBatis-Plus

  1. 导入依赖
1
2
3
4
5
6
<!-- https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-generator -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.5.3</version>
</dependency>
  • 还需要加入模板依赖
1
2
3
4
5
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>2.2</version>
</dependency>
  1. 编写生成器代码
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
public static void main(String[] args) {
FastAutoGenerator.create("jdbc:mysql://localhost:3306/mybatis_plus?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=UTC", "root", "123456")
.globalConfig(builder -> { // 全局配置
builder.author("bayyy") // 作者
.disableOpenDir() // 禁用打开输出目录
.outputDir(System.getProperty("user.dir") + "/src/main/java") // 输出目录
.enableSwagger() // 开启swagger模式
.dateType(DateType.ONLY_DATE) // 时间类型
.commentDate("yyyy-MM-dd"); // 注释日期格式
})
.packageConfig(builder -> { // 包配置
builder.parent("com.bayyy") // 父包名
.moduleName("mybatis_plus") // 父包模块名
.entity("pojo") // 实体类包名
.service("service") // service包名
.serviceImpl("service.impl") // serviceImpl包名
.mapper("dao") // mapper包名
.xml("dao.mapper") // mapper XML包名
.controller("controller") // controller包名
.pathInfo(null); // 路径配置信息
})
.strategyConfig(builder -> { // 策略配置
builder.addInclude("user") // 指定生成的表名(默认null)
.addTablePrefix("t_") // 表名前缀(默认null, 如果指定了表名前缀, 生成的实体类名将会去除前缀)
.addFieldSuffix("_flag") // 字段名后缀(默认null, 如果指定了字段名后缀, 生成的实体类字段名将会去除后缀)
.enableCapitalMode() // 开启全局大写命名(默认false, 例如: 表名 user -> 实体类名 User)
/* 实体类配置 */
.entityBuilder() // 实体类配置
.enableLombok() // 开启lombok(默认false)
.columnNaming(NamingStrategy.underline_to_camel) // 字段命名策略(默认underline_to_camel:下划线转驼峰命名)
.naming(NamingStrategy.underline_to_camel) // 实体命名策略(默认underline_to_camel:下划线转驼峰命名)
.addTableFills(new Column("update_time", FieldFill.INSERT)) // 表字段填充(默认null)
.addTableFills(new Column("create_time", FieldFill.INSERT_UPDATE)) // 表字段填充(默认null)
.versionColumnName("version") // 乐观锁字段名(默认null)
.idType(IdType.AUTO) // 主键类型(默认null, 改为IdType.AUTO即可使用自增主键)
.logicDeleteColumnName("deleted") // 逻辑删除字段名(默认null)
/* Service 配置 */
.serviceBuilder() // service配置
.enableFileOverride() // 开启文件覆盖(默认false)
.formatServiceImplFileName("%sServiceImpl") // service实现类命名格式(默认null)
.formatServiceFileName("%sService") // service接口命名格式(默认null)
/* Controller 配置 */
.controllerBuilder()
.enableRestStyle() // 开启restController(默认false)
.enableHyphenStyle() // 开启驼峰转连字符(默认false, 例如: 表名 user, 字段名 id -> localhost:8080/user_id_1)
.build();
})
.execute();

}
}
  • 测试结果:image-20230810175741203