目录
1.MyBatis-Plus介绍
2.MyBatis-Plus快速入门
3.MyBatis-Plus配置日志
4.MyBatis-Plus扩展CRUD
4.1 主键生成策略(对应Insert操作)
4.2 自动填充功能(对应Insert和Update操作)
4.3 乐观锁插件(对应Update操作)
4.4 分页查询(对应Select操作)
4.5 逻辑删除(对应Delete操作)
5.条件构造器
6.代码自动生成器
1.MyBatis-Plus介绍
进入MyBatis-Plus的官网即可看到其介绍:为简化开发而生!
Mybatis的诞生就是为了简化JDBC操作,而MyBatis-Plus(简称 MP)是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。
MyBatis-Plus的官方文档对其特性进行了说明:
- 无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
- 损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作(提供一些BaseMapper,实现了各种CRUD的操作,只需要通过泛型传入实体类)
- 强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求(简单和基础的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.MyBatis-Plus快速入门
为了尽快的感受到上述提到的MyBatis-Plus的优势,首先推荐跟着官方文档做一下快速入门的案例。
第一步,导入依赖,并去掉mybatis的依赖,避免版本差异和依赖冲突等奇怪问题:
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.3.2</version>
</dependency>
第二步,配置数据源,同mybatis的使用一样,并且同样在 Spring Boot 启动类中添加 @MapperScan(value = "cn.korb1n.springbootproject.mapper")
注解,扫描 Mapper 文件夹。
第三步,也是最后一步,只需要创建poji
实体类和Mapper接口
,Mapper接口继承BaseMapper
即可使用常用的基础CRUD操作(通过泛型传入实体类)。
package cn.korb1n.springbootproject.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.sql.Date;
import java.sql.Timestamp;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private Long id;
private String telephone;
private String password;
private String nickname;
private Date birthday;
private Integer gender;
private String email;
private Integer type;
private String headUrl;
private Timestamp createTime;
private Timestamp updateTime;
}
package cn.korb1n.springbootproject.mapper;
import cn.korb1n.springbootproject.pojo.User;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.springframework.stereotype.Repository;
@Repository //避免IDEA中使用@Autowired注解报红
public interface UserMapper extends BaseMapper<User> {
}
注意:由于我的数据库user表中的字段名采用的是驼峰的形式,而不是下划线的实行,在MyBatis-Plus中,如User类中的headUrl规定应该对应数据库表中的head_url字段,而数据库中也是headUrl,所以需要关闭MyBatis-Plus中的驼峰映射到下划线,否则会报错。在application.yml配置文件中添加配置:
mybatis-plus: configuration: #关闭下划线驼峰映射 map-underscore-to-camel-case: false
测试使用:
@SpringBootTest
class SpringbootProjectApplicationTests {
@Autowired
private UserMapper userMapper;
@Test
public void contextLoads() {
//参数为一个Wrapper实例,是条件构造器,相当于SQL操作的条件,赋null不填写就是无任何条件
List<User> users = userMapper.selectList(null);
for (User user:users){
System.out.println(user);
}
}
}
控制台输出:
通过以上几个简单的步骤,我们就实现了 User 表的 CRUD 功能, 完全不用编写XML 文件!所以我们可以看到集成MyBatis-Plus非常的简单,只需要引入 starter 工程,并配置 mapper 扫描路径即可。
3.MyBatis-Plus配置日志
现在MyBatis-Plus虽然已经快速使用了一遍,但是所有的SQL目前都是不可见的,如果我们希望看到MyBatis-Plus是如何执行的,我们需要查看日志输出,进而对MyBatis-Plus进行日志配置:
mybatis-plus:
configuration:
#关闭下划线驼峰映射
map-underscore-to-camel-case: false
#配置日志,控制台输出
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
日志输出:
对日志进行配置后,在使用过程中可以逐渐了解到MyBatis-Plus对SQL的处理操作方式和感受到上述提到的MyBatis-Plus的特性。
4.MyBatis-Plus扩展CRUD
MyBatis-Plus已经为我们简化了很多操作,即便如此,我们很多对于数据库的操作还可以继续简化,还可以进一步的自动化,我们可以对很多功能进行扩展,新增插件。
4.1 主键生成策略(对应Insert操作)
测试执行Insert插入操作:
@Test
public void contextLoads() {
User user = new User(null, "13518468755", "123456", "hello", new Date(System.currentTimeMillis()), 1, "", 0, "", new Timestamp(System.currentTimeMillis()), null);
int result = userMapper.insert(user);
System.out.println(result);
System.out.println(user);
}
运行结果如下,通过日志输出可以发现MyBatis-Plus在做插入数据操作时会为插入的记录自动生成id,并且会自动回填到插入的User对象。另外,该id既不是数据库表的自增id(数据库表我设置了自增),也不是uuid等。
实际上上述采用的是雪花算法
,这是在做任何设置情况下主键生成策略默认的方式。
另外,我们还可以通过MyBatis-Plus提供的@TableId
注解的type
参数来改变主键生成策略。使用方式只需要添加在实体类的id成员变量上,加了该注解后就不会再使用上述的雪花算法,而是使用注解中指定的策略。如下是官方文档对该注解的详细说明:
属性 | 类型 | 必须指定 | 默认值 | 描述 |
---|---|---|---|---|
value | String | 否 | “” | 主键字段名 |
type | Enum | 否 | IdType.NONE | 主键类型 |
type参数的枚举值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 长整型类型(please use ASSIGN_ID) | |
32位UUID字符串(please use ASSIGN_UUID) | |
分布式全局唯一ID 字符串类型(please use ASSIGN_ID) |
@TableId(type = IdType.AUTO)
private Long id;
添加注解将主键生成策略修改为自增后,运行插入测试代码后新插入的记录id确实变为了自增。
4.2 自动填充功能(对应Insert和Update操作)
在数据库中有个这个情况,就是几乎所有的表都需要创建时间
和修改时间
这两个字段,如果我们每次都在插入数据或者更新数据时去操作这两个字段,显然还是有点麻烦。所以一般我们有两种方式来自动填充这两个字段。
第一种方式,在数据库级别做操作。将createTime
和updateTime
两个字段的默认值都设置为CURRENT_TIMESTAMP
,这样在插入时,将自动初始化这两个字段;并且将updateTime
字段设置为根据当前时间更新
,表示某条记录数据更新时,updateTime
字段将自动更新为当前时间。在Navicat中的设置如下图所示:
第二种方式是在代码级别做操作。 上述直接在数据库中操作一般是不推荐的,通常我们使用代码级别的操作。MyBatis-Plus提供了@TableField
注解来设置字段在指定操作下做自动填充操作。实现方式为第一步直接将注解添加到需要自动填充的字段:
@TableField(fill = FieldFill.INSERT)
private Timestamp createTime;
@TableField(fill = FieldFill.INSERT_UPDATE)
private Timestamp updateTime;
该注解的fill参数枚举值FieldFill:
值 | 描述 |
---|---|
DEFAULT | 默认不处理 |
INSERT | 插入时填充字段 |
UPDATE | 更新时填充字段 |
INSERT_UPDATE | 插入和更新时填充字段 |
第二步需要做一个配置即可。配置在做这些数据库操作的情况下,给加了注解的字段填充什么类型的数据,配置类如下,最新可参考MyBatis-Plus的官方文档:
@Slf4j
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
log.info("start insert fill ....");
Timestamp now = new Timestamp(System.currentTimeMillis());
this.strictInsertFill(metaObject, "createTime", Timestamp.class, now); // 起始版本 3.3.0(推荐使用)
this.strictInsertFill(metaObject, "updateTime", Timestamp.class, now); // 起始版本 3.3.0(推荐使用)
// this.fillStrategy(metaObject, "createTime", LocalDateTime.now()); // 也可以使用(3.3.0 该方法有bug请升级到之后的版本如`3.3.1.8-SNAPSHOT`)
/* 上面选其一使用,下面的已过时(注意 strictInsertFill 有多个方法,详细查看源码) */
//this.setFieldValByName("operator", "Jerry", metaObject);
//this.setInsertFieldValByName("operator", "Jerry", metaObject);
}
@Override
public void updateFill(MetaObject metaObject) {
log.info("start update fill ....");
this.strictUpdateFill(metaObject, "updateTime", Timestamp.class, new Timestamp(System.currentTimeMillis())); // 起始版本 3.3.0(推荐使用)
// this.fillStrategy(metaObject, "updateTime", LocalDateTime.now()); // 也可以使用(3.3.0 该方法有bug请升级到之后的版本如`3.3.1.8-SNAPSHOT`)
/* 上面选其一使用,下面的已过时(注意 strictUpdateFill 有多个方法,详细查看源码) */
//this.setFieldValByName("operator", "Tom", metaObject);
//this.setUpdateFieldValByName("operator", "Tom", metaObject);
}
}
测试更新操作后查看日志,自动为我们进行了updateTime的更新:
4.3 乐观锁插件(对应Update操作)
简单乐观锁介绍基本概念:
1.乐观锁:顾名思义十分乐观, 总是认为不会出现问题,无论干什么都不去上锁!如果意外的出现了问题,一般进行多次更新测试。乐观锁的实现方式是每次更新都会携带一个版本号
version
字段,通过该版本号是否更新来确认数据是否在操作过程中被其他人更新了。
例如A线程正在执行更新操作:update user set nickname='Korbin', version=version+1 where id=1 and version=1
时,另外一个B线程已经抢先完成了对该条记录的更新操作:update user set nickname='Korbin22222', version=version+1 where id=1 and version=1
,这时B线程完成更新后version值这时已经变成2,而A线程用1去判断version,则会更新失败。
2.悲观锁:区别于乐观锁,也是顾名思义,该锁十分悲观,认为总是会出现问题,无论干什么都会进行上锁,保证数据安全,然后再去操作。
所以首先在数据库表字段中添加version
字段,默认为0即可,并同步在实体类中添加version成员变量,然后在该字段上加上@Version
注解,注意该注解是mybatisplus包下的。
@Version
private Integer version;
最后需要通过配置类注册乐观锁组件,由于其是用于MyBatis-Plus的专用配置类,所以还可以将原先主启动类上的@MapperScan
注解移到该配置类上,最后开启事务@EnableTransactionManagement
,默认也开启了:
@Configuration
@EnableTransactionManagement
@MapperScan(value = "cn.korb1n.springbootproject.mapper")
public class MyBatisPlusConfig {
/**
* 注册乐观锁插件
* @return
*/
@Bean
public OptimisticLockerInterceptor optimisticLockerInterceptor() {
return new OptimisticLockerInterceptor();
}
}
①首先测试运行乐观锁成功的更新操作:
@Test
public void contextLoads() {
User user = userMapper.selectById(100007L);
user.setNickname("hello_new33");
int result = userMapper.updateById(user);
System.out.println(result);
System.out.println(user);
}
查看控制台输出日志,可以知道version自动实现了自加:
②然后测试运行模拟乐观锁失败的更新操作,
@Test
public void contextLoads() {
//模拟线程1,查询出了用户信息并设置了值,待做更新操作
User user1 = userMapper.selectById(100007L);
//user1.setUpdateTime(null);手动赋空
user1.setNickname("zhangsan");
//但这时另一个线程插队进行了更新操作
User user2 = userMapper.selectById(100007L);
user2.setNickname("lisi");
userMapper.updateById(user2);
//线程1执行更新操作
//会更新失败,如果没有乐观锁则会覆盖插队线程的值;如果用户继续操作则会采用自旋锁多次尝试提交
userMapper.updateById(user1);
}
由于乐观锁需要用到oldVsersion值,所以需要先通过id取出了version,这就会导致updateTime
非空了,进而导致自动填充失效,updateTime
字段不会更新。虽然官方说strictUpdateFill
方法会强制填充,但我测试时是没有进行自动填充的,所以如果出现该问题,可以将updateTime
赋null
,你可以在插入前手动赋null
,也可以在自动填充处理器中全局赋null
:
@Override
public void updateFill(MetaObject metaObject) {
log.info("start update fill ....");
//赋null,实现强制自动填充
if (metaObject.getValue("updateTime")!=null){
metaObject.setValue("updateTime",null);
}
this.strictUpdateFill(metaObject, "updateTime", Timestamp.class, new Timestamp(System.currentTimeMillis()));
}
通过控制台日志输出可以发现:线程1被线程2抢先完成更新操作后,此时的version值已经更新为11,但线程1还拿着10去做更新操作,自然就失败了。
4.4 分页查询(对应Select操作)
以前做分页查询时,我们通常都是自己手写limit
进行分页,或者用第三方分页插件pageHelper
等。现在MyBatis-Plus内置了分页插件,虽然其底层也是用limit
去显示的,但为我们做了大量封装,我们只需要从面向对象的角度去调用接口即可,不需要自己再写大量代码或者花多余的成本(时间精力)去整合第三方插件。
在使用分页插件之前我们只需要在之前添加的MyBatisPlusConfig
中配置分页插件的拦截器,因为这些插件本质就是通过拦截器去实现的:
/**
* 分页查询插件
* @return
*/
@Bean
public PaginationInterceptor paginationInterceptor() {
PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
// 设置请求的页面大于最大页后操作, true调回到首页,false 继续请求 默认false
// paginationInterceptor.setOverflow(false);
// 设置最大单页限制数量,默认 500 条,-1 不受限制
// paginationInterceptor.setLimit(500);
// 开启 count 的 join 优化,只针对部分 left join
paginationInterceptor.setCountSqlParser(new JsqlParserCountOptimize(true));
return paginationInterceptor;
}
测试运行分页插件的基本使用:
@Test
public void contextLoads() {
Page<User> page = new Page<>(1,3);
page = userMapper.selectPage(page, null);
page.getRecords().forEach(System.out::println);
System.out.println("总数:"+page.getTotal());
System.out.println("总页数:"+page.getPages());
}
查看控制台日志信息可以验证其底层确实也是用的limit
来操作,并且在分页查询前,都首先会查询总条数:
4.5 逻辑删除(对应Delete操作)
对数据库数据的删除我们可以分为两种:
- 物理删除:直接将数据擦除,删掉。
- 逻辑删除:并没有真正删除,数据仍然存在于数据库中,只是通过一个如
deleted
这样的字段来将该条记录标记为删除,只是从逻辑上认为被删除了。(相当于只是将数据放到了回收站,有需要还可以恢复数据)
按照官方文档的描述介绍逻辑删除:
说明:
只对自动注入的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: 配置com.baomidou.mybatisplus.core.config.GlobalConfig$DbConfig
,在application.yml
中:
mybatis-plus:
global-config:
db-config:
logic-delete-field: flag # 全局逻辑删除的实体字段名(since 3.3.0,配置后可以忽略不配置步骤2,如指定为deleted)
logic-delete-value: 1 # 逻辑已删除值(默认为 1)
logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
步骤2: 实体类字段上加上@TableLogic
注解:
@TableLogic
private Integer deleted;
常见问题:
1.如何 insert ?
- 字段在数据库定义默认值(推荐)
- insert 前自己 set 值
- 使用自动填充功能
2.删除接口自动填充功能失效:
- 使用 update 方法并: UpdateWrapper.set(column, value)(推荐)
- 使用 update 方法并: UpdateWrapper.setSql(“column=value”)
- 使用Sql注入器注入
com.baomidou.mybatisplus.extension.injector.methods.LogicDeleteByIdWithFill
并使用(推荐)
测试运行:
@Test
public void contextLoads() {
userMapper.deleteById(100007L);
userMapper.selectById(100007);
}
通过控制台日志输出可以发现,指定了逻辑删除后,删除操作实际为了更新操作,改变deleted
字段的状态即可。并且在查询操作时,会自动带上deleted
字段,过滤掉逻辑上删除了的数据。
5.条件构造器
MyBatis-Plus为我们提供了一些简单的、基础的和常用的数据库操作方式,但一些特殊的和复杂的操作方式,仍然需要由我们自己来完成。但是为了简化我们的SQL操作,MyBatis-Plus为我们提供了条件构造器,就是各种Wrapper
,这个Wrapper
有点类似于JAVA中的Map
,我们只需要设置或者传入SQL条件参数即可。
示例测试运行:
@Test
public void contextLoads() {
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.isNotNull("headUrl").ge("id",100001L);
userMapper.selectList(wrapper);
}
通过控制台的日志输出可以看到,使用条件控制器Wrapper后,查询条件拼接到了语句后面,并且查询出来的数据符合条件:
再演示一个示例:
@Test
public void contextLoads() {
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.like("nickname","in")//模糊查询
.inSql("id","select id from user where id>=100000")//子查询,可以做联表查询
.orderByDesc("id");//按id升序排序
userMapper.selectList(wrapper);
}
对上面用到的和其他的条件参数说明,请参考MyBatis-Plus官方文档对添加构造器的说明MyBatis-Plus 条件构造器 。
6.代码自动生成器
MyBatis-Plus同Mybatis一样有代码生成器,并且MyBatis-Plus提供了更多生成的内容,如Serivce和Controller,还有上述提到的自动填充、乐观锁、逻辑删除等,另外还有Swagger2等,都可以通过配置后自动生成。极大的提升了开发效率,减少了开发成本。
相较于Mybatis使用xml进行配置的方式,MyBatis-Plus使用的是直接在代码中进行配置的方式,这对于对xml不熟或者厌恶xml配置的小伙伴来说,是一件非常爽的事。
首先添加 代码生成器 依赖:
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.3.2</version>
</dependency>
<!-- MP代码生成器需要的模版引擎依赖-->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>2.2</version>
</dependency>
<!-- MYSQL驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- 非SpringBoot项目用这个-->
<!-- <dependency>-->
<!-- <groupId>mysql</groupId>-->
<!-- <artifactId>mysql-connector-java</artifactId>-->
<!-- <version>8.0.21</version>-->
<!-- </dependency>-->
并附上其他用到的插件等的依赖,避免代码生成后没有依赖报红:
<!-- lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
</dependency>
<!-- swagger-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
MyBatis-Plus 的代码生成器提供了大量的自定义参数供用户选择,能够满足绝大部分人的使用需求。
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.PackageConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.po.TableFill;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import java.util.ArrayList;
import java.util.List;
/**
* MyBatis-Plus代码自动生成器
* 更多详细配置,请参考官方文档 https://mp.baomidou.com/config/generator-config.html
* @author Korbin
*/
public class CodeAutoGenerator {
/**
* 代码生成器
*/
private static AutoGenerator mpg = new AutoGenerator();
public static void main(String[] args) {
//全局配置
GlobalConfig gc = new GlobalConfig();
//获取项目文件绝对路径
String projectPath = System.getProperty("user.dir");
//设置生成代码的输出目录:项目文件下的/src/main/java目录下
gc.setOutputDir(projectPath + "/src/main/java");
//设置作者名
gc.setAuthor("Korbin");
//代码生成完成后是否打开代码文件所在Windows的文件夹
gc.setOpen(false);
//是否覆盖原先生成的代码文件
gc.setFileOverride(false);
//是否配置上实体属性 Swagger2 注解
gc.setSwagger2(true);
//设置生成Service代码文件名,默认的含有I前缀
gc.setServiceName("%sService");
//设置主键生成策略
gc.setIdType(IdType.AUTO);
//设置数据库表字段对应实体类中的日期类型:根据数据库类型而定
gc.setDateType(DateType.SQL_PACK);
//将全局配置应用到代码生成器
mpg.setGlobalConfig(gc);
//数据源配置
DataSourceConfig dsc = new DataSourceConfig();
dsc.setDbType(DbType.MYSQL);
dsc.setUrl("jdbc:mysql://localhost:3306/personal_community?useUnicode=true&useSSL=false&characterEncoding=utf8&serverTimezone=GMT%2B8");
// dsc.setSchemaName("public");
dsc.setDriverName("com.mysql.cj.jdbc.Driver");
dsc.setUsername("root");
dsc.setPassword("hezebin19980525");
mpg.setDataSource(dsc);
//包配置
PackageConfig pc = new PackageConfig();
//设置生成代码各个包所放的包名,即模块名
// pc.setModuleName("模块名");
//设置模块名的父包,一般为域名逆序
pc.setParent("top.korbin");
//设置实体类包名
pc.setEntity("pojo");
mpg.setPackageInfo(pc);
// 自定义配置
InjectionConfig cfg = new InjectionConfig() {
@Override
public void initMap() {
// to do nothing
}
};
//策略配置
StrategyConfig strategy = new StrategyConfig();
//设置表名支持下划线转驼峰
strategy.setNaming(NamingStrategy.underline_to_camel);
//设置表中列名(字段名)支持下划线转驼峰
strategy.setColumnNaming(NamingStrategy.underline_to_camel);
//是否开启lombok注解
strategy.setEntityLombokModel(true);
//设置Controller默认为@RestController,返回JSON数据
strategy.setRestControllerStyle(true);
//设置要映射生成代码的表名,可变长参数,可设置多个表名
strategy.setInclude("user");
//设置数据库表名前缀,生成的实体类不包含模块名和下划线
// strategy.setTablePrefix(pc.getModuleName() + "_");
//设置逻辑删除的标记字段名
strategy.setLogicDeleteFieldName("deleted");
//设置自动填充字段策略
List<TableFill> tableFillList = new ArrayList<TableFill>();
tableFillList.add(new TableFill("create_time", FieldFill.INSERT));
tableFillList.add(new TableFill("update_time", FieldFill.INSERT_UPDATE));
strategy.setTableFillList(tableFillList);
//设置乐观锁字段
strategy.setVersionFieldName("version");
//localhost:8080/hello_id_2
strategy.setControllerMappingHyphenStyle(true);
mpg.setStrategy(strategy);
mpg.execute();
}
}
更多详细配置,请参考官方说明文档 代码生成器配置 一文。