1. 背景:
プロジェクト開発プロセスでは、自動化ツールを使用して ORM オブジェクト リレーショナル マッピングを生成することが重要なタスクです。
mybatis plus ジェネレーターは非常に便利なツールです。新しく構築されたプロジェクトで、研究開発兄弟は何か新しいことを試みました。彼らはジェネレーターの 3.5.1 および 3.5.2 バージョンを使用しました。それに付属する基本ツール クラスの生成に基づいて、同時に生成したかったのですが、PO、VO、DTO、変換ツールなどの対応エンティティに関して、3.5.1以降のカスタマイズに関する情報が少ないことがわかったので、記録するためにこの記事を書きました。研究結果。それが米国にとって良いことを願う
2. mybatis plus ジェネレーター jar パッケージの導入
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus</artifactId>
<version>3.5.1</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.5.1</version>
</dependency>
3. 開発環境の概要
mac、jdk 1.8、idea、mysql、Velocity テンプレートを使用して生成ツール クラスをカスタマイズします (デフォルト)
4. 基本的な設定手順
1. 基本的なパス情報の設定
/**数据库链接地址**/
private static final String JDBC_URL_MAN = "jdbc:mysql://127.0.0.1:3306/myDatabase?useUnicode=true&characterEncoding=UTF-8";
/**数据库登录账号**/
private static final String JDBC_UserName = "root";
/**数据库登录密码**/
private static final String JDBC_Password = "root1234";
/**
* 【需要修改】
* 需要进行生成文件的表名
* 多张表,表名间使用,号分割
**/
private static final String[] Tables = { "user_table"};
/**
* 【需要修改】
* 生成类的注释
* 作者名称
*/
private static final String CODE_AUTHOR = "timerbin";
/**
* 生成的文件存放地址 之
* 文件路径
*/
private static final String FILE_STORAGE_FILE_ROOT_PATH = System.getProperty("user.dir")+"/user-obj/user-obj-dao/src/test/java/";
/**
* 生成的文件存放地址 之
* 父级 jar包路径
*/
private static final String FILE_STORAGE_FILE_JAR_PACKAGE = "com.jd.timer.bin.user.dao";
/**
*
* 生成的文件存放地址 之
* 模块 jar包名称
*/
private static final String FILE_STORAGE_FILE_JAR_PACKAGE_MODULE = "build";
/**
* 生成的文件存放地址 之
* Service 接口 存放地址
*/
private static final String FILE_STORAGE_SERVICE_FILE_JAR_PACKAGE= "service";
/**
* 生成的文件存放地址 之
* Service impl 实现类 存放地址
*/
private static final String FILE_STORAGE_SERVICE_IMPL_FILE_JAR_PACKAGE= "impl";
/**
* 生成的文件存放地址 之
* entity 实体类 存放地址
*/
private static final String FILE_STORAGE_ENTITY_FILE_JAR_PACKAGE= "entity";
/**
* 生成的文件存放地址 之
* mapper 操作类 存放地址
*/
private static final String FILE_STORAGE_MAPPER_FILE_JAR_PACKAGE= "mapper";
/**
* 生成的文件存放地址 之
* mapper xml 文件 存放地址
*/
private static final String FILE_STORAGE_MAPPER_XML_FILE_JAR_PACKAGE= "mapper";
/**
* 自定义 、定制 生成的文件存放地址 之
* other 其他文件 存放地址
*/
private static final String FILE_STORAGE_OTHER_FILE_JAR_PACKAGE= "other";
上記の設定の主な目的は、データベース、テーブル、生成される基本ファイルの保存パスを指定することですが、ここではあまり注意して下を見る必要はありません。
2. ツールのメインメソッドを自動生成する
public static void main(String[] args) {
//设置数据库信息
/***
* 数据库信息配置
*/
DataSourceConfig dataSourceConfig = configDataSource();
/**
* 生成工具类
**/
AutoGenerator generator = new AutoGenerator(dataSourceConfig);
/**
* 全局变量配置
*/
generator.global(configGlobel());
/**
* 设置生成文件包名地址
*/
generator.packageInfo(configPackage());
/**
* 生成文件的策略配置
*/
generator.strategy(configStratgy());
/**
* 生成的类的模板配置
*/
generator.template(configTemplate());
/**
* 自定义实体信息
**/
generator.injection(initInjectionConfig());
/**
* 自定义模板解析器
*/
YaoVelocityTemplateEngine yaoVelocityTemplateEngine = new YaoVelocityTemplateEngine();
generator.execute(yaoVelocityTemplateEngine);
}
関連する jar パッケージのリファレンス
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.IFill;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.converts.MySqlTypeConvert;
import com.baomidou.mybatisplus.generator.config.querys.MySqlQuery;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.DbColumnType;
import com.baomidou.mybatisplus.generator.config.rules.IColumnType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.fill.Column;
import com.baomidou.mybatisplus.generator.keywords.MySqlKeyWordsHandler;
3. 主要なサブメソッド
/**
* 配置基础转换器
* @return
*/
private static DataSourceConfig configDataSource() {
/**数据库链接配置**/
DataSourceConfig dataSourceConfig = new DataSourceConfig.Builder(
JDBC_URL_MAN,
JDBC_UserName,
JDBC_Password
)
.dbQuery(new MySqlQuery())
/**自定义转换器,将tinyint 转换为Integer**/
.typeConvert(new EasyMySqlTypeConvert())
.keyWordsHandler(new MySqlKeyWordsHandler())
.build();
return dataSourceConfig;
}
/**
* 自定义转换器转换器 内部类
* 目的将数据库表中定义的 tinyint 或 bit类型转变为 java Integer 类型
* @author timerbin
*/
static class EasyMySqlTypeConvert extends MySqlTypeConvert {
@Override
public IColumnType processTypeConvert(GlobalConfig config, String fieldType) {
IColumnType iColumnType = super.processTypeConvert(config, fieldType);
if (fieldType.equals("tinyint(1)")) {
iColumnType = DbColumnType.INTEGER;
}
if (fieldType.equals("bit(1)")) {
iColumnType = DbColumnType.BYTE;
}
return iColumnType;
}
}
/**
* 设置全局变量
* @return
*/
private static GlobalConfig configGlobel() {
GlobalConfig globalConfig = new GlobalConfig.Builder()
.fileOverride()
.disableOpenDir()
/**存放生成文件的文件夹地址**/
.outputDir(FILE_STORAGE_FILE_ROOT_PATH)
.author(CODE_AUTHOR)
.dateType(DateType.ONLY_DATE)
.commentDate("yyyy-MM-dd hh:mm:ss")
.build();
return globalConfig;
}
/**
* 生成文件存储目录配置
* @return
*/
private static PackageConfig configPackage() {
PackageConfig packageConfig = new PackageConfig.Builder()
/**存放生成文件的 父级 package 地址**/
.parent(FILE_STORAGE_FILE_JAR_PACKAGE)
/**存放生成文件的 的 父级模块地址**/
.moduleName(FILE_STORAGE_FILE_JAR_PACKAGE_MODULE)
/**存放生成文件的 service 接口 存放的package地址**/
.service(FILE_STORAGE_SERVICE_FILE_JAR_PACKAGE)
/**存放生成文件的 service 接口实现类 存放的package地址**/
.serviceImpl(FILE_STORAGE_SERVICE_IMPL_FILE_JAR_PACKAGE)
/**存放生成文件的 实体类 存放的package地址**/
.entity(FILE_STORAGE_ENTITY_FILE_JAR_PACKAGE)
/**存放生成文件的 mapper 操作类 存放的package地址**/
.mapper(FILE_STORAGE_MAPPER_FILE_JAR_PACKAGE)
/**存放生成文件的 mapper 操作类 xml 存放的package地址**/
.xml(FILE_STORAGE_MAPPER_XML_FILE_JAR_PACKAGE)
/**存放生成文件的 其他实体类 存放的package地址**/
.other(FILE_STORAGE_OTHER_FILE_JAR_PACKAGE)
.build();
return packageConfig;
}
/**
* 生成文件的策略配置
* @return
*/
private static StrategyConfig configStratgy() {
/**
* 初始化配置
* 策略中实体字段的默认填充装置
*
*/
List<IFill> tableFillList = makeInitTableFills();
StrategyConfig strategyConfig = new StrategyConfig.Builder()
.addInclude(Tables)
.entityBuilder()//开始定制实体
/***禁用生成 serialVersionUID**/
// .disableSerialVersionUID()
.enableActiveRecord()
.enableLombok()
.enableRemoveIsPrefix()
.enableTableFieldAnnotation()
.enableChainModel()
.naming(NamingStrategy.underline_to_camel)
.columnNaming(NamingStrategy.underline_to_camel)
/***逻辑删除字段名(数据库)**/
// .logicDeleteColumnName("yn")
.addTableFills(tableFillList)
.idType(IdType.AUTO)
/**格式化实体类文件名称***/
//.formatFileName("%sEntity")
.serviceBuilder()//开始定制Service,由于我们不需要service此处略
/***格式化 service 接口文件名称**/
.formatServiceFileName("%sService")
.formatServiceImplFileName("%sServiceImpl")
.mapperBuilder()//开始定制映射器
.enableMapperAnnotation()
.superClass(BaseMapper.class)
.enableBaseColumnList()
.enableBaseResultMap()
.formatMapperFileName("%sMapper")
.formatXmlFileName("%sMapper")
.build();
return strategyConfig;
}
/**
* 类生成策略
* 配置字段默认填充装置
*
* @return
*/
private static List<IFill> makeInitTableFills(){
List<IFill> tableFillList = new ArrayList<>();
/**定义创建时间 插入时默认填充**/
Column createTableFill = new Column("created", FieldFill.INSERT);
/** 定义修改时间 插入或修改时默认填充**/
Column updateTableFill = new Column("modified", FieldFill.INSERT_UPDATE);
tableFillList.add(createTableFill);
tableFillList.add(updateTableFill);
return tableFillList;
}
/**
* 设置其他模板
* @return
*/
private static TemplateConfig configTemplate() {
TemplateConfig templateConfig = new TemplateConfig.Builder()
.controller(null)//我不需要controller 此处传null
.service(null)//我不需要service 此处传null
.serviceImpl(null)//我不需要service impl 此处传null
.build();
return templateConfig;
}
/**
*
* @return
*/
private static InjectionConfig initInjectionConfig(){
/**自定义生成模板参数**/
Map<String,Object> paramMap = new HashMap<>();
/** 自定义 生成类**/
Map<String,String> customFileMap = new HashMap<>();
/**PO实体**/
customFileMap.put("po"+File.separator+"%sPO.java", "/templates/PO.java.vm");
/**Vo实体**/
customFileMap.put("vo"+File.separator+"%sVO.java", "/templates/VO.java.vm");
/**DTO实体**/
customFileMap.put("dto"+File.separator+"%sDTO.java", "/templates/DTO.java.vm");
return new InjectionConfig.Builder()
.customMap(paramMap)
.customFile(customFileMap)
.build();
}
上記の構成は、主に mybatis plus ジェネレーター 3.5.1 の基本構成です。インターネット上に関連する手順が多数あるため、ここでは詳しく説明しません。次の記事はより完全であり、そこから学ぶことができます。
詳細については、mybatis-plus コード ジェネレーターと構成 - BlogMemory - Blog Parkを参照してください。
5. 説明の重視 – カスタマイズとカスタマイズツール
1. 主な構成メソッドは上記のコードにリストされています。これは initInjectionConfig() メソッドであり、構成情報を同期する必要があります。
//1、指定生成的自定文件存放路径
/**存放生成文件的 其他实体类 存放的package地址**/
new PackageConfig.Builder().other(FILE_STORAGE_OTHER_FILE_JAR_PACKAGE);
//2、自定义重新生成自定义、定制类的工具
/**
* 自定义模板解析器
*/
TimerVelocityTemplateEngine timerVelocityTemplateEngine = new TimerVelocityTemplateEngine();
//3、定义注入配置方法
/**
* 自定义注入配置
* @return
*/
private static InjectionConfig initInjectionConfig(){
/**自定义生成模板参数**/
Map<String,Object> paramMap = new HashMap<>();
/** 自定义 生成类**/
Map<String,String> customFileMap = new HashMap<>();
/**PO实体**/
customFileMap.put("po"+File.separator+"%sPO.java", "/templates/PO.java.vm");
/**Vo实体**/
customFileMap.put("vo"+File.separator+"%sVO.java", "/templates/VO.java.vm");
/**DTO实体**/
customFileMap.put("dto"+File.separator+"%sDTO.java", "/templates/DTO.java.vm");
return new InjectionConfig.Builder()
.customMap(paramMap)
.customFile(customFileMap)
.build();
}
//4、将自定义注入配置放入到 自动工具生成器中
/**
* 自定义实体信息
**/
generator.injection(initInjectionConfig());
//开始执行基础类生成
generator.execute(timerVelocityTemplateEngine);
2. InjectionConfig 注入構成のプロパティに注目してみましょう。
方法 | 説明する | 効果 |
beforeOutputFile(BiConsumer<TableInfo, Map<String, Object>>) | コンシューマの前の出力ファイル | |
CustomMap(Map<String, Object>) | カスタム構成のマップ オブジェクト key: 渡されるパラメータの名前 値: パラメータとして渡されるオブジェクト |
パラメータと値をカスタム テンプレートに渡す |
CustomFile(Map<String, String>) | カスタム構成テンプレート ファイル マップ key: 生成されたカスタムおよびカスタマイズされたクラスの名前を定義するために使用されます。 値: カスタムおよびカスタマイズされたクラスのテンプレート アドレスを指定するために使用されます。デフォルトは Velocity テンプレートです。 |
カスタムテンプレート名とテンプレート |
3.書き換えられたYaoVelocityTemplateEngineクラスを詳しく説明する
書き換え後のコード:
import com.baomidou.mybatisplus.generator.config.OutputFile;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.engine.VelocityTemplateEngine;
import com.jd.jsf.gd.util.JsonUtils;
public class TimerVelocityTemplateEngine extends VelocityTemplateEngine {
@Override
protected void outputCustomFile( Map<String, String> customFile, TableInfo tableInfo,Map<String, Object> objectMap) {
//数据库表映射实体名称
String entityName = tableInfo.getEntityName();
String otherPath = this.getPathInfo(OutputFile.other);
//System.out.println(JsonUtils.toJSONString(tableInfo));
//数据库表映射实体名称 驼峰命名法
objectMap.put("humpEentityName",toLowerCaseFirstOne(entityName));
customFile.forEach((key, value) -> {
String fileName = String.format(otherPath + File.separator +key,entityName);
this.outputFile(new File(fileName), objectMap, value);
});
}
/**
* 首字母转为小写
* @param s
* @return
*/
private String toLowerCaseFirstOne(String s){
if(Character.isLowerCase(s.charAt(0))) {
return s;
}else {
return (new StringBuilder()).append(Character.toLowerCase(s.charAt(0))).append(s.substring(1)).toString();
}
}
}
書き換え前のソースコード:
//AbstractTemplateEngine
protected void outputCustomFile(@NotNull Map<String, String> customFile, @NotNull TableInfo tableInfo, @NotNull Map<String, Object> objectMap) {
String entityName = tableInfo.getEntityName();
String otherPath = this.getPathInfo(OutputFile.other);
customFile.forEach((key, value) -> {
String fileName = String.format(otherPath + File.separator + entityName + File.separator + "%s", key);
this.outputFile(new File(fileName), objectMap, value);
});
}
書き換えの理由:
1) Velocity テンプレートに関連する属性が見つかりませんでした。データベース テーブル マッピング エンティティ名のキャメル ケース命名メソッドを取得できます。使いやすいように、このメソッドを書き換えてキャメル ケース エンティティ クラスの命名を取得します。
2. カスタムクラスやカスタマイズクラスを複数生成する場合、ファイルパスを任意に指定することができず、似たような名前が複数あると探すのが非常に困難になります。
3. ソース コード メソッドを使用するとき、データベース テーブル マッピング エンティティ名をカスタマイズまたはカスタム生成されたクラス名に追加する方法をまったく考えていませんでした。
以上の操作により、カスタマイズされたエンティティ情報を実現できます。
6. 速度テンプレートの場合
package ${package.Other}.po;
import lombok.Getter;
import lombok.Setter;
import java.io.Serializable;
import java.util.Date;
/**
* <p>
* $!{table.comment} 数据表 ${humpEentityName} 数据库表映射实体驼峰名称
* 基础设施层请求实体
* </p>
*
* @author ${author}
* @since ${date}
*/
@Getter
@Setter
public class ${entity}PO implements Serializable {
private static final long serialVersionUID = 1L;
#foreach($field in ${table.fields})
#if(${field.keyFlag})
#set($keyPropertyName=${field.propertyName})
#end
#if("$!field.comment" != "")
/**
* ${field.comment}
*/
#end
private ${field.propertyType} ${field.propertyName};
#end
/**
* 当前页
*/
private Integer page = 1;
/**
* 每页条数
*/
private Integer pageSize = 20;
}
Velocity の上記の関連構成については、ここでは説明しません。mybatis plusgenerator 3.5.1 jar パッケージの基本テンプレートを直接確認して、他の構成を見つけることができます。また、InjectionConfig # beforeOutputFile メソッドを使用して、すべての入力パラメータを出力することもできます入力パラメーターを使用することも、InjectionConfig #customMap メソッドを通じて入力パラメーターをカスタマイズすることもできます。
上の図からわかるように、mybatis plusgenerator 3.5.1 は jar 内で複数の生成テンプレートをサポートしていますが、Velocity はその 1 つであり、好みに応じて対応するテンプレートを選択できます。
7. まとめ
mybatis plus ジェネレーターのソースコードは比較的シンプルで、ソースコードを通じてカスタマイズして開発できます。