mirror of
https://gitee.com/mybatis-flex/mybatis-flex.git
synced 2025-12-07 09:08:24 +08:00
516 lines
12 KiB
Markdown
516 lines
12 KiB
Markdown
# Mybatis-Flex 代码生成器
|
||
|
||
在 mybatis-flex 的模块 `mybatis-flex-codegen` 中,提供了可以通过数据库表,生成 Entity 类和 Mapper 类的功能。当我们把数据库表设计完成
|
||
后可以使用其快速生成 Entity 和 Mapper 的 java 类。
|
||
|
||
在使用前先添加 `mybatis-flex-codegen` 的 Maven 依赖:
|
||
|
||
```xml
|
||
<dependency>
|
||
<groupId>com.mybatis-flex</groupId>
|
||
<artifactId>mybatis-flex-codegen</artifactId>
|
||
<version>1.2.3</version>
|
||
</dependency>
|
||
```
|
||
|
||
同时需要添加数据源的 Maven 依赖和 jdbc 驱动依赖:
|
||
|
||
```xml
|
||
<dependency>
|
||
<groupId>com.zaxxer</groupId>
|
||
<artifactId>HikariCP</artifactId>
|
||
<version>4.0.3</version>
|
||
</dependency>
|
||
|
||
<dependency>
|
||
<groupId>mysql</groupId>
|
||
<artifactId>mysql-connector-java</artifactId>
|
||
<version>8.0.32</version>
|
||
</dependency>
|
||
```
|
||
|
||
然后,编写一个任意带有 main 方法的类,如下所示:
|
||
|
||
```java
|
||
public class Codegen {
|
||
|
||
public static void main(String[] args) {
|
||
|
||
//配置数据源
|
||
HikariDataSource dataSource = new HikariDataSource();
|
||
dataSource.setJdbcUrl("jdbc:mysql://127.0.0.1:3306/your-database?characterEncoding=utf-8");
|
||
dataSource.setUsername("root");
|
||
dataSource.setPassword("******");
|
||
|
||
//创建配置内容
|
||
GlobalConfig globalConfig = new GlobalConfig();
|
||
|
||
//设置根包
|
||
globalConfig.getPackageConfig()
|
||
.setBasePackage("com.test");
|
||
|
||
//设置表前缀和只生成哪些表
|
||
globalConfig.getStrategyConfig()
|
||
.setTablePrefix("tb_")
|
||
.addGenerateTable("account", "account_session");
|
||
|
||
//设置生成 entity 并启用 Lombok
|
||
globalConfig.enableEntity()
|
||
.setWithLombok(true);
|
||
|
||
//设置生成 mapper
|
||
globalConfig.enableMapper();
|
||
|
||
//可以单独配置某个列
|
||
ColumnConfig columnConfig = new ColumnConfig();
|
||
columnConfig.setColumnName("tenant_id");
|
||
columnConfig.setLarge(true);
|
||
columnConfig.setVersion(true);
|
||
globalConfig.getStrategyConfig()
|
||
.addColumnConfig("account", columnConfig);
|
||
|
||
//通过 datasource 和 globalConfig 创建代码生成器
|
||
Generator generator = new Generator(dataSource, globalConfig);
|
||
|
||
//生成代码
|
||
generator.generate();
|
||
}
|
||
}
|
||
```
|
||
|
||
注意:由于 MyBatis-Flex 的 APT 功能会自动帮我们生成了 Mapper 的 Java 类,如果我们在代码生成器中选择生成 Mapper,
|
||
则建议把 APT 的 Mapper 生成功能给关闭掉,否则系统中会存在两份一样功能的 Mapper。
|
||
|
||
关闭 APT 的 Mapper 类文件生成,请参考:[APT 设置章节](../others/apt.md)
|
||
|
||
## 使用介绍
|
||
|
||
在 Mybatis-Flex 的代码生成器中,支持如下 6 种类型的的产物生成:
|
||
|
||
- Entity 实体类
|
||
- Mapper 映射类
|
||
- TableDef 表定义辅助类
|
||
- Service 服务类
|
||
- ServiceImpl 服务实现类
|
||
- Controller 控制类
|
||
|
||
启用或关闭某种类型产物的生成,代码如下:
|
||
|
||
```java
|
||
|
||
// 开启 Entity 的生成
|
||
globalConfig.enableEntity();
|
||
// 关闭 Entity 的生成
|
||
globalConfig.disableEntity();
|
||
|
||
```
|
||
|
||
所有方法均支持链式调用配置,代码如下:
|
||
|
||
```java
|
||
|
||
// 设置生成 Entity 并启用 Lombok、设置父类
|
||
globalConfig.enableEntity()
|
||
.setWithLombok(true)
|
||
.setSupperClass(BaseEntity.class);
|
||
|
||
```
|
||
|
||
## 全局配置 `GlobalConfig`
|
||
|
||
GlobalConfig 全局配置项包含多个子配置项:
|
||
|
||
```java
|
||
|
||
public class GlobalConfig {
|
||
|
||
private final PackageConfig packageConfig;
|
||
private final StrategyConfig strategyConfig;
|
||
|
||
private EntityConfig entityConfig;
|
||
private MapperConfig mapperConfig;
|
||
private ServiceConfig serviceConfig;
|
||
private ServiceImplConfig serviceImplConfig;
|
||
private ControllerConfig controllerConfig;
|
||
private TableDefConfig tableDefConfig;
|
||
|
||
private Map<String, Object> customConfig;
|
||
|
||
}
|
||
|
||
```
|
||
|
||
## 包配置 `PackageConfig`
|
||
|
||
PackageConfig 支持的配置如下:
|
||
|
||
```java
|
||
|
||
public class PackageConfig {
|
||
|
||
//代码生成目录。
|
||
private String sourceDir;
|
||
|
||
//根包。
|
||
private String basePackage = "com.mybatisflex";
|
||
|
||
//Entity 所在包。
|
||
private String entityPackage;
|
||
|
||
//Mapper 所在包。
|
||
private String mapperPackage;
|
||
|
||
//Service 所在包。
|
||
private String servicePackage;
|
||
|
||
//ServiceImpl 所在包。
|
||
private String serviceImplPackage;
|
||
|
||
//Controller 所在包。
|
||
private String controllerPackage;
|
||
|
||
//TableDef 所在包。
|
||
private String tableDefPackage;
|
||
|
||
}
|
||
```
|
||
|
||
## 策略配置 `StrategyConfig`
|
||
|
||
StrategyConfig 支持的配置如下:
|
||
|
||
```java
|
||
|
||
public class StrategyConfig {
|
||
|
||
//数据库表前缀,多个前缀用英文逗号(,) 隔开。
|
||
private String tablePrefix;
|
||
|
||
//逻辑删除的默认字段名称。
|
||
private String logicDeleteColumn;
|
||
|
||
//乐观锁的字段名称。
|
||
private String versionColumn;
|
||
|
||
//是否生成视图映射。
|
||
private boolean generateForView;
|
||
|
||
//是否覆盖之前生成的文件。
|
||
private boolean overwriteEnable;
|
||
|
||
//单独为某张表添加独立的配置。
|
||
private Map<String, TableConfig> tableConfigMap;
|
||
|
||
//设置某个列的全局配置。
|
||
private Map<String, ColumnConfig> defaultColumnConfigMap;
|
||
|
||
//生成那些表,白名单。
|
||
private Set<String> generateTables;
|
||
|
||
//不生成那些表,黑名单。
|
||
private Set<String> unGenerateTables;
|
||
|
||
//使用哪个模板引擎来生成代码。
|
||
protected ITemplate templateEngine;
|
||
|
||
}
|
||
```
|
||
|
||
## Entity 生成配置 `EntityConfig`
|
||
|
||
EntityConfig 支持的配置如下:
|
||
|
||
```java
|
||
|
||
public class EntityConfig {
|
||
|
||
//Entity 类的前缀。
|
||
private String classPrefix = "";
|
||
|
||
//Entity 类的后缀。
|
||
private String classSuffix = "";
|
||
|
||
//Entity 类的父类,可以自定义一些 BaseEntity 类。
|
||
private Class<?> supperClass;
|
||
|
||
//Entity 默认实现的接口。
|
||
private Class<?>[] implInterfaces = {Serializable.class};
|
||
|
||
//Entity 是否使用 Lombok 注解。
|
||
private boolean withLombok;
|
||
|
||
}
|
||
```
|
||
|
||
## Mapper 生成配置 `MapperConfig`
|
||
|
||
MapperConfig 支持的配置如下:
|
||
|
||
```java
|
||
|
||
public class MapperConfig {
|
||
|
||
//Mapper 类的前缀。
|
||
private String classPrefix = "";
|
||
|
||
//Mapper 类的后缀。
|
||
private String classSuffix = "Mapper";
|
||
|
||
//自定义 Mapper 的父类。
|
||
private Class<?> supperClass = BaseMapper.class;
|
||
|
||
}
|
||
```
|
||
|
||
## Service 生成配置 `ServiceConfig`
|
||
|
||
ServiceConfig 支持的配置如下:
|
||
|
||
```java
|
||
|
||
public class ServiceConfig {
|
||
|
||
//Service 类的前缀。
|
||
private String classPrefix = "";
|
||
|
||
//Service 类的后缀。
|
||
private String classSuffix = "Service";
|
||
|
||
//自定义 Service 的父类。
|
||
private Class<?> supperClass = IService.class;
|
||
|
||
}
|
||
```
|
||
|
||
## ServiceImpl 生成配置 `ServiceImplConfig`
|
||
|
||
ServiceImplConfig 支持的配置如下:
|
||
|
||
```java
|
||
|
||
public class ServiceImplConfig {
|
||
|
||
//ServiceImpl 类的前缀。
|
||
private String classPrefix = "";
|
||
|
||
//ServiceImpl 类的后缀。
|
||
private String classSuffix = "ServiceImpl";
|
||
|
||
//自定义 ServiceImpl 的父类。
|
||
private Class<?> supperClass = ServiceImpl.class;
|
||
|
||
}
|
||
```
|
||
|
||
## Controller 生成配置 `ControllerConfig`
|
||
|
||
ControllerConfig 支持的配置如下:
|
||
|
||
```java
|
||
|
||
public class ControllerConfig {
|
||
|
||
//Controller 类的前缀。
|
||
private String classPrefix = "";
|
||
|
||
//Controller 类的后缀。
|
||
private String classSuffix = "Controller";
|
||
|
||
//自定义 Controller 的父类。
|
||
private Class<?> supperClass;
|
||
|
||
//生成 REST 风格的 Controller。
|
||
private boolean restStyle = true;
|
||
|
||
}
|
||
```
|
||
|
||
## TableDef 生成配置 `TableDefConfig`
|
||
|
||
TableDefConfig 支持的配置如下:
|
||
|
||
```java
|
||
|
||
public class TableDefConfig {
|
||
|
||
//TableDef 类的前缀。
|
||
private String classPrefix = "";
|
||
|
||
//TableDef 类的后缀。
|
||
private String classSuffix = "Def";
|
||
|
||
}
|
||
```
|
||
|
||
## 表配置 `TableConfig`
|
||
|
||
TableConfig 支持的配置如下:
|
||
|
||
```java
|
||
public class TableConfig {
|
||
|
||
private String tableName;
|
||
|
||
/**
|
||
* 数据库的 schema
|
||
*/
|
||
private String schema;
|
||
|
||
/**
|
||
* 默认为 驼峰属性 转换为 下划线字段
|
||
*/
|
||
private Boolean camelToUnderline;
|
||
|
||
|
||
private Class<? extends InsertListener> insertListenerClass;
|
||
|
||
|
||
private Class<? extends UpdateListener> updateListenerClass;
|
||
|
||
// 是否启用ATP生成Mapper
|
||
private Boolean mapperGenerateEnable = Boolean.TRUE;
|
||
}
|
||
```
|
||
|
||
## 列配置 `ColumnConfig`
|
||
|
||
ColumnConfig 支持的配置如下:
|
||
|
||
```java
|
||
public class ColumnConfig implements Serializable {
|
||
|
||
private String onInsertValue;
|
||
private String onUpdateValue;
|
||
|
||
private Boolean isLarge;
|
||
private Boolean isLogicDelete;
|
||
private Boolean version;
|
||
|
||
private JdbcType jdbcType;
|
||
private Class<? extends TypeHandler> typeHandler;
|
||
|
||
private String mask;
|
||
|
||
private boolean isPrimaryKey = false;
|
||
private KeyType keyType;
|
||
private String keyValue;
|
||
private Boolean keyBefore;
|
||
|
||
// 是否是租户列
|
||
private Boolean tenantId;
|
||
}
|
||
```
|
||
|
||
## 自定义属性类型
|
||
|
||
Mybatis-Flex 内置了一个名为:`JdbcTypeMapping` 的 java 类,我们可以用其配置映射 Jdbc 驱动的数据类型为自定义的
|
||
数据类型,在开始生成代码之前,可以先调用其进行配置,例如:
|
||
|
||
```java
|
||
JdbcTypeMapping.registerMapping(LocalDateTime.class, Date.class);
|
||
```
|
||
那么,当我们生成代码的时候,发现 JDBC 驱动的数据类型为 `LocalDateTime`,则 Entity 对应的属性类型为 `Date`。
|
||
|
||
## 自定义代码模板
|
||
|
||
通过 `GlobalConfig`(全局配置)的 `setTemplateEngine()` 方法,可以配置自己的模板引擎以及模板,以下是内置的 `EnjoyTemplate` 的代码示例:
|
||
|
||
```java
|
||
public class EnjoyTemplate implements ITemplate {
|
||
|
||
private Engine engine;
|
||
|
||
public EnjoyTemplate() {
|
||
engine = Engine.create("mybatis-flex", engine -> {
|
||
engine.setToClassPathSourceFactory();
|
||
engine.addSharedMethod(StringUtil.class);
|
||
});
|
||
Engine.addFieldGetterToFirst(new FieldGetters.IsMethodFieldGetter());
|
||
}
|
||
|
||
/**
|
||
* 生成 entity 的方法实现
|
||
*/
|
||
@Override
|
||
public void generateEntity(GlobalConfig globalConfig, Table table, File entityJavaFile) throws Exception {
|
||
Map<String, Object> params = new HashMap<>();
|
||
params.put("globalConfig", globalConfig);
|
||
params.put("table", table);
|
||
|
||
|
||
FileOutputStream fileOutputStream = new FileOutputStream(entityJavaFile);
|
||
engine.getTemplate("/templates/enjoy/entity.tpl").render(params, fileOutputStream);
|
||
}
|
||
|
||
|
||
/**
|
||
* 生成 mapper 的方法实现
|
||
*/
|
||
@Override
|
||
public void generateMapper(GlobalConfig globalConfig, Table table, File mapperJavaFile) throws Exception {
|
||
Map<String, Object> params = new HashMap<>();
|
||
params.put("globalConfig", globalConfig);
|
||
params.put("table", table);
|
||
|
||
|
||
FileOutputStream fileOutputStream = new FileOutputStream(mapperJavaFile);
|
||
engine.getTemplate("/templates/enjoy/mapper.tpl").render(params, fileOutputStream);
|
||
}
|
||
}
|
||
```
|
||
|
||
## 添加其他产物的生成
|
||
|
||
通过实现 `IGenerator` 来实现,比如 Entity 实体类的代码如下:
|
||
|
||
```java
|
||
public class EntityGenerator implements IGenerator {
|
||
|
||
private String templatePath = "/templates/enjoy/entity.tpl";
|
||
|
||
@Override
|
||
public void generate(Table table, GlobalConfig globalConfig) {
|
||
|
||
if (!globalConfig.isEntityGenerateEnable()) {
|
||
return;
|
||
}
|
||
|
||
PackageConfig packageConfig = globalConfig.getPackageConfig();
|
||
StrategyConfig strategyConfig = globalConfig.getStrategyConfig();
|
||
|
||
String entityPackagePath = packageConfig.getEntityPackage().replace(".", "/");
|
||
File entityJavaFile = new File(packageConfig.getSourceDir(), entityPackagePath + "/" +
|
||
table.buildEntityClassName() + ".java");
|
||
|
||
|
||
if (entityJavaFile.exists() && !strategyConfig.isOverwriteEnable()) {
|
||
return;
|
||
}
|
||
|
||
|
||
Map<String, Object> params = new HashMap<>(3);
|
||
params.put("table", table);
|
||
params.put("packageConfig", packageConfig);
|
||
params.put("entityConfig", globalConfig.getEntityConfig());
|
||
|
||
strategyConfig.getTemplateEngine().generate(params, templatePath, entityJavaFile);
|
||
}
|
||
}
|
||
```
|
||
|
||
如果我们想生成其他产物,比如 `html` ,可以通过编写自己的类,来实现 IGenerator 接口,例如:
|
||
|
||
```java
|
||
public class HtmlGenerator implements IGenerator {
|
||
|
||
@Override
|
||
public void generate(Table table, GlobalConfig globalConfig) {
|
||
//在这里生成 html 代码
|
||
}
|
||
}
|
||
```
|
||
最后,通过 `GeneratorFactory` 来注册 `HtmlGenerator` 即可:
|
||
|
||
```java
|
||
GeneratorFactory.registerGenerator("html",new HtmlGenerator());
|
||
``` |