MyBatis Generator
MyBatis Generator 是MyBatis的快速代码生成工具,它将为MyBatis的所有版本生成代码(entity, 基础的CRUD方法的dao, mapper)。尽管已经提供了大量的配置标签,但是每个公司都有自己的代码规范, 那就只能自己上手扩展了。
一.MyBatis Generator可以通过以下方式运行
- 用命令行运行MBG
- 使用ant运行
- 作为Maven插件
- 使用Java运行
- 作为Eclipse的插件
二. Mybatis Generator使用
- 依赖
org.mybatis.generator
mybatis-generator-core
1.4.0
mysql
mysql-connector-java
8.0.16
- 配置文件
- 执行,生成代码
把第二步的xml文件作为configFile传入
ConfigurationParser cp = new ConfigurationParser(warnings);
Configuration config = cp.parseConfiguration(configFile);
DefaultShellCallback callback = new DefaultShellCallback(overwrite);
MyBatisGenerator myBatisGenerator = null;
myBatisGenerator = new MyBatisGenerator(config, callback, warnings);
myBatisGenerator.generate(null);
三.MyBatis Generator XML配置介绍
配置文件告诉MBG:
- 如何连接数据库
- 为哪些表生成对象
- 生成什么对象(model,client,map xml),以及如何生成它们
GeneratorXML配置文件:
1.
一个context可以看作一个数据库环境。
可以在
2. 或者
设置数据库连接。
3.
生成crud,可以设置生成的文件放在哪个包
3.
生成entity,可以设置生成的文件放在哪个包
一些主要功能
- 是否生成全字段构造函数
- 是否immutable,将决定是否生成set方法
- set方法是否自动trim
4.
用于定义SQL映射生成器的属性,当选择的javaClientGenerator需要XML时,此元素才是
5.
用于定义 Java 类型解析器的属性。Java 类型解析器决定了 数据库列 与 Java类型的对应关系
6.
定义注释生成器的属性
7.
设置entity类名生成规则
比如当库中的所有表都有一个公共前缀,但是我们的entity名字里面不想要这个前缀
8.
指定表,为该表生成代码(entity, crud方法, mapper)
一些主要配置项:
- entity的名字
- 是否使用真实列名作为属性名(否则就用驼峰)
- 是否生成根据主键的select|delete|update
- 是否生成插入语句
- 是否允许主键查询
- 是否immutable,将决定是否生成set方法
8.1
用于指定自动生成的字段(比如自增id)
如果指定此元素,则MyBatis Generator(MBG)将在SQL映射的生成的元素内生成一个适当的
元素(根据sqlStatement不同而不同),insert的时候会把这个值赋值到对象中。
MySql -> SELECT LAST_INSERT_ID()
8.2.
- property设置java属性名(一般不需要在columnOverride这个标签里面设置,可以在table标签统一设置成驼峰)
- 制定列与属性的映射关系
- isGeneratedAlways=true 生成的insert update方法就不会去设置这个字段的值。
- typeHandler当默认的类型转换不能满足要求的时候可以自定义类型转换
8.3.
忽略某列,所有生成的代码里面都不会包含这列。
8.4.
根据正则忽略列,可以指定except,这样正则就可以写得更加简单了。
8.5.
设置entity中属性名生成规则
比如当表中的所有列都有一个公共前缀,但是我们的entity里面不想要这个前缀。
四.目前使用默认的generator存在的问题
看默认生成的sql和方法,存在一些问题,不太好用
public interface MbgTestMapper {
@Delete({
"delete from mbg_test",
"where id = #{id,jdbcType=BIGINT}"
})
int deleteByPrimaryKey(Long id);
@Insert({
"insert into mbg_test (status, ",
"version, created_time, ",
"another_status, ",
"msg, long_msg)",
"values (#{status,jdbcType=TINYINT,typeHandler=com.myproject.core.mybatis.typehandler.IntEnumTypeHandler}, ",
"#{version,jdbcType=INTEGER}, #{createdTime,jdbcType=TIMESTAMP}, ",
"#{anotherStatus,jdbcType=TINYINT,typeHandler=com.myproject.core.mybatis.typehandler.IntEnumTypeHandler}, ",
"#{msg,jdbcType=LONGVARCHAR}, #{longMsg,jdbcType=LONGVARCHAR})"
})
@SelectKey(statement="SELECT LAST_INSERT_ID()", keyProperty="id", before=false, resultType=Long.class)
int insert(MbgTest record);
@Select({
"select",
"id, status, version, created_time, another_status, msg, long_msg",
"from mbg_test",
"where id = #{id,jdbcType=BIGINT}"
})
@Results({
@Result(column="id", property="id", jdbcType=JdbcType.BIGINT, id=true),
@Result(column="status", property="status", typeHandler=IntEnumTypeHandler.class, jdbcType=JdbcType.TINYINT),
@Result(column="version", property="version", jdbcType=JdbcType.INTEGER),
@Result(column="created_time", property="createdTime", jdbcType=JdbcType.TIMESTAMP),
@Result(column="another_status", property="anotherStatus", typeHandler=IntEnumTypeHandler.class, jdbcType=JdbcType.TINYINT),
@Result(column="msg", property="msg", jdbcType=JdbcType.LONGVARCHAR),
@Result(column="long_msg", property="longMsg", jdbcType=JdbcType.LONGVARCHAR)
})
MbgTest selectByPrimaryKey(Long id);
@Select({
"select",
"id, status, version, created_time, another_status, msg, long_msg",
"from mbg_test"
})
@Results({
@Result(column="id", property="id", jdbcType=JdbcType.BIGINT, id=true),
@Result(column="status", property="status", typeHandler=IntEnumTypeHandler.class, jdbcType=JdbcType.TINYINT),
@Result(column="version", property="version", jdbcType=JdbcType.INTEGER),
@Result(column="created_time", property="createdTime", jdbcType=JdbcType.TIMESTAMP),
@Result(column="another_status", property="anotherStatus", typeHandler=IntEnumTypeHandler.class, jdbcType=JdbcType.TINYINT),
@Result(column="msg", property="msg", jdbcType=JdbcType.LONGVARCHAR),
@Result(column="long_msg", property="longMsg", jdbcType=JdbcType.LONGVARCHAR)
})
List selectAll();
@Update({
"update mbg_test",
"set status = #{status,jdbcType=TINYINT,typeHandler=com.myproject.core.mybatis.typehandler.IntEnumTypeHandler},",
"version = #{version,jdbcType=INTEGER},",
"created_time = #{createdTime,jdbcType=TIMESTAMP},",
"another_status = #{anotherStatus,jdbcType=TINYINT,typeHandler=com.myproject.core.mybatis.typehandler.IntEnumTypeHandler},",
"msg = #{msg,jdbcType=LONGVARCHAR},",
"long_msg = #{longMsg,jdbcType=LONGVARCHAR}",
"where id = #{id,jdbcType=BIGINT}"
})
int updateByPrimaryKey(MbgTest record);
}
1. 缺少乐观锁支持,导致生成的update,delete方法,容易被误用。
自定义pluginAdater,生成updateByVersion方法,deleteByVersion方法,原有的update/delete方法就不要生成了,防止误用。
自动生成的代码如下
@Update({
"update mbg_test",
"set status = #{status,jdbcType=TINYINT,typeHandler=com.myproject.core.mybatis.typehandler.IntEnumTypeHandler},",
"version = version+1,",
"created_time = #{createdTime,jdbcType=TIMESTAMP},",
"another_status = #{anotherStatus,jdbcType=TINYINT,typeHandler=com.myproject.core.mybatis.typehandler.IntEnumTypeHandler},",
"msg = #{msg,jdbcType=LONGVARCHAR},",
"long_msg = #{longMsg,jdbcType=LONGVARCHAR}",
"where id = #{id,jdbcType=BIGINT}",
"and version = #{version,jdbcType=BIGINT}"
})
int updateByIdAndVersion(MbgTest record);
但是这个方法并不会抛出异常,可以考虑再自动生成default方法来处理异常(具体异常类可以在配置文件里面自由修改)
2. BLOB字段支持还不友好,我们还需要自己写select/update方法 (分别需要实现 带blob字段和不带blob字段的方法)
自定义pluginAdater
目前这里只做了生成一个不含blob字段的select语句。可以考虑生成一套不含blob字段的select/update方法。返回值的问题还没想好(是再生成一个不含blob字段的entity还是生成一个dto,或者说直接使用全字段的entity)
static final String SELECT_FIELDS_WITHOUT_BLOB = "select status, version, created_time, another_status from mbg_test ";
3. 缺少批量操作的方法
自定义pluginAdater后生成代码如下
@Insert({
""
})
int insertAll(@Param("records") List records);
4. 生成方法的名字不太符合我们的风格
public class CustomIntrospectedTableMyBatis3Ipl extends IntrospectedTableMyBatis3SimpleImpl {
@Override
protected void calculateXmlAttributes() {
super.calculateXmlAttributes();
setSelectByPrimaryKeyStatementId("findById");
setDeleteByPrimaryKeyStatementId("delete");
setUpdateByPrimaryKeyStatementId("update");
}
}
5. LocalDateTime支持
public class CustomJavaTypeResolver extends JavaTypeResolverDefaultImpl {
public CustomJavaTypeResolver() {
super();
typeMap.put(Types.TIMESTAMP, new JdbcTypeInformation("TIMESTAMP",
new FullyQualifiedJavaType(LocalDateTime.class.getName())));
}
}
6. 写别的方法的时候不想写select *的话就得把字段给拷贝一遍,不方便维护(表上改了,代码忘记改了或者改漏了)
自定义pluginAdater,使得把字段给提取一个变量出来,后面自己写方法的时候就可以引用了。
生成的代码:
static final String SELECT_ALL_FIELDS = "select id, status, version, created_time, another_status, msg, long_msg from mbg_test ";
7. 枚举类的支持
mybatis提供了自定义的typeHandler。在使用mybatis generator的时候指定typeHandler即可。
8. 期望可以生成一个resultMap的id"), 不用再写一遍映射关系
自定义pluginAdater,在findById方法生成后,修改一下方法的annotation加上id
扩展后自动生成代码如下
@Select({
"select",
"id, status, version, created_time, another_status, msg, long_msg",
"from mbg_test",
"where id = #{id,jdbcType=BIGINT}"
})
@Results(value = {
@Result(column="id", property="id", jdbcType=JdbcType.BIGINT, id=true),
@Result(column="status", property="status", typeHandler=IntEnumTypeHandler.class, jdbcType=JdbcType.TINYINT),
@Result(column="version", property="version", jdbcType=JdbcType.BIGINT),
@Result(column="created_time", property="createdTime", jdbcType=JdbcType.TIMESTAMP),
@Result(column="another_status", property="anotherStatus", typeHandler=IntEnumTypeHandler.class, jdbcType=JdbcType.TINYINT),
@Result(column="msg", property="msg", jdbcType=JdbcType.LONGVARCHAR),
@Result(column="long_msg", property="longMsg", jdbcType=JdbcType.LONGVARCHAR)
}, id="mbgTest")
MbgTest findById(Long id);
五.源码简单解读
1. 最外层,读取 然后挨个处理
一个context对应一个数据库
// 读取 然后挨个处理
contextsToRun = configuration.getContexts();
// methods related to code generation.
// Methods should be called in this order:
// 1.获取分析步骤(对于每个context来说有两步,1连接数据库,2分析表)
context.getIntrospectionSteps();
// 2.分析需要生成代码的相关表
context.introspectTables(callback, warnings, fullyQualifiedTableNames);
// 3.获取生成文件的步骤
context.getGenerationSteps();
// 4.获取需要生成的文件
// 每个context处理好后会把结果放到generatedJavaFiles,generatedXmlFiles,generatedKotlinFiles三个列表中
context.generateFiles(callback, generatedJavaFiles,
generatedXmlFiles, generatedKotlinFiles, warnings);
// 写文件
for (GeneratedXmlFile gxf : generatedXmlFiles) {
projects.add(gxf.getTargetProject());
writeGeneratedXmlFile(gxf, callback);
}
for (GeneratedJavaFile gjf : generatedJavaFiles) {
projects.add(gjf.getTargetProject());
writeGeneratedJavaFile(gjf, callback);
}
for (GeneratedKotlinFile gkf : generatedKotlinFiles) {
projects.add(gkf.getTargetProject());
writeGeneratedKotlinFile(gkf, callback);
}
2. 分析表introspectTables
// 1.获取类型处理器
JavaTypeResolver javaTypeResolver = ObjectFactory
.createJavaTypeResolver(this, warnings);
// 2.获取数据库分析器,分析表
DatabaseIntrospector databaseIntrospector = new DatabaseIntrospector(
this, connection.getMetaData(), javaTypeResolver, warnings);
databaseIntrospector.introspectTables(tc);
// 分析字段,包括1. 排除忽略字段,2.获取列的元数据,并根据元数据得出对应的java类型和属性名 3.应用的设置 4.处理字段相关
removeIgnoredColumns(tc, columns);
calculateExtraColumnInformation(tc, columns);
applyColumnOverrides(tc, columns);
calculateIdentityColumns(tc, columns);
// 分析表的元数据,并且得到类名,主键信息等
List introspectedTables = calculateIntrospectedTables(
tc, columns);
3. 生成文件内容generateFiles(以client生成为例)
ps:官方提供了PluginAdater,调用Plugin的地方都是我们可以插入自己逻辑的地方
// 1.获取插件列表,plugin.validate为true的才会加入
pluginAggregator = new PluginAggregator();
Plugin plugin = ObjectFactory.createPlugin(this,
pluginConfiguration);
// 2.生成interface
Interface interfaze = new Interface(type);
// 3. 生成基本方法
addDeleteByPrimaryKeyMethod(interfaze);
addInsertMethod(interfaze);
addSelectByPrimaryKeyMethod(interfaze);
addSelectAllMethod(interfaze);
addUpdateByPrimaryKeyMethod(interfaze);
// 4. 调用Plugin的方法(这个时候我们可以在plugin里面往interfaze上面挂任何我们想要的代码)
if (context.getPlugins().clientGenerated(interfaze, introspectedTable)) {
answer.add(interfaze);
}
4. 官方提供的methodGenerator
// 1.生成方法
Method method = new Method(introspectedTable.getDeleteByPrimaryKeyStatementId());
// 2.annotation
addMapperAnnotations(method);
// 3.调用plugin对应的方法(我们可以在这里修改这个method,或者阻止这个method生成)
if (context.getPlugins().clientDeleteByPrimaryKeyMethodGenerated(
method, interfaze, introspectedTable)) {
// 4.添加import
addExtraImports(interfaze);
interfaze.addImportedTypes(importedTypes);
// 5.把这个方法挂到interface上面
interfaze.addMethod(method);
}
六.定制mybatis generator的切入点---PluginAdapter
PluginAdapter提供了丰富的逻辑切入点,这些方法会在mybatis generator的各个环节被触发。而且运行的上下文环境(context),配置(properties)会被注入其中。
你可能感兴趣的:(定制MyBatis Generator减少mybatis的使用负担)
8.5.
设置entity中属性名生成规则
比如当表中的所有列都有一个公共前缀,但是我们的entity里面不想要这个前缀。
四.目前使用默认的generator存在的问题
看默认生成的sql和方法,存在一些问题,不太好用
public interface MbgTestMapper {
@Delete({
"delete from mbg_test",
"where id = #{id,jdbcType=BIGINT}"
})
int deleteByPrimaryKey(Long id);
@Insert({
"insert into mbg_test (status, ",
"version, created_time, ",
"another_status, ",
"msg, long_msg)",
"values (#{status,jdbcType=TINYINT,typeHandler=com.myproject.core.mybatis.typehandler.IntEnumTypeHandler}, ",
"#{version,jdbcType=INTEGER}, #{createdTime,jdbcType=TIMESTAMP}, ",
"#{anotherStatus,jdbcType=TINYINT,typeHandler=com.myproject.core.mybatis.typehandler.IntEnumTypeHandler}, ",
"#{msg,jdbcType=LONGVARCHAR}, #{longMsg,jdbcType=LONGVARCHAR})"
})
@SelectKey(statement="SELECT LAST_INSERT_ID()", keyProperty="id", before=false, resultType=Long.class)
int insert(MbgTest record);
@Select({
"select",
"id, status, version, created_time, another_status, msg, long_msg",
"from mbg_test",
"where id = #{id,jdbcType=BIGINT}"
})
@Results({
@Result(column="id", property="id", jdbcType=JdbcType.BIGINT, id=true),
@Result(column="status", property="status", typeHandler=IntEnumTypeHandler.class, jdbcType=JdbcType.TINYINT),
@Result(column="version", property="version", jdbcType=JdbcType.INTEGER),
@Result(column="created_time", property="createdTime", jdbcType=JdbcType.TIMESTAMP),
@Result(column="another_status", property="anotherStatus", typeHandler=IntEnumTypeHandler.class, jdbcType=JdbcType.TINYINT),
@Result(column="msg", property="msg", jdbcType=JdbcType.LONGVARCHAR),
@Result(column="long_msg", property="longMsg", jdbcType=JdbcType.LONGVARCHAR)
})
MbgTest selectByPrimaryKey(Long id);
@Select({
"select",
"id, status, version, created_time, another_status, msg, long_msg",
"from mbg_test"
})
@Results({
@Result(column="id", property="id", jdbcType=JdbcType.BIGINT, id=true),
@Result(column="status", property="status", typeHandler=IntEnumTypeHandler.class, jdbcType=JdbcType.TINYINT),
@Result(column="version", property="version", jdbcType=JdbcType.INTEGER),
@Result(column="created_time", property="createdTime", jdbcType=JdbcType.TIMESTAMP),
@Result(column="another_status", property="anotherStatus", typeHandler=IntEnumTypeHandler.class, jdbcType=JdbcType.TINYINT),
@Result(column="msg", property="msg", jdbcType=JdbcType.LONGVARCHAR),
@Result(column="long_msg", property="longMsg", jdbcType=JdbcType.LONGVARCHAR)
})
List selectAll();
@Update({
"update mbg_test",
"set status = #{status,jdbcType=TINYINT,typeHandler=com.myproject.core.mybatis.typehandler.IntEnumTypeHandler},",
"version = #{version,jdbcType=INTEGER},",
"created_time = #{createdTime,jdbcType=TIMESTAMP},",
"another_status = #{anotherStatus,jdbcType=TINYINT,typeHandler=com.myproject.core.mybatis.typehandler.IntEnumTypeHandler},",
"msg = #{msg,jdbcType=LONGVARCHAR},",
"long_msg = #{longMsg,jdbcType=LONGVARCHAR}",
"where id = #{id,jdbcType=BIGINT}"
})
int updateByPrimaryKey(MbgTest record);
}
1. 缺少乐观锁支持,导致生成的update,delete方法,容易被误用。
自定义pluginAdater,生成updateByVersion方法,deleteByVersion方法,原有的update/delete方法就不要生成了,防止误用。
自动生成的代码如下
@Update({
"update mbg_test",
"set status = #{status,jdbcType=TINYINT,typeHandler=com.myproject.core.mybatis.typehandler.IntEnumTypeHandler},",
"version = version+1,",
"created_time = #{createdTime,jdbcType=TIMESTAMP},",
"another_status = #{anotherStatus,jdbcType=TINYINT,typeHandler=com.myproject.core.mybatis.typehandler.IntEnumTypeHandler},",
"msg = #{msg,jdbcType=LONGVARCHAR},",
"long_msg = #{longMsg,jdbcType=LONGVARCHAR}",
"where id = #{id,jdbcType=BIGINT}",
"and version = #{version,jdbcType=BIGINT}"
})
int updateByIdAndVersion(MbgTest record);
但是这个方法并不会抛出异常,可以考虑再自动生成default方法来处理异常(具体异常类可以在配置文件里面自由修改)
2. BLOB字段支持还不友好,我们还需要自己写select/update方法 (分别需要实现 带blob字段和不带blob字段的方法)
自定义pluginAdater
目前这里只做了生成一个不含blob字段的select语句。可以考虑生成一套不含blob字段的select/update方法。返回值的问题还没想好(是再生成一个不含blob字段的entity还是生成一个dto,或者说直接使用全字段的entity)
static final String SELECT_FIELDS_WITHOUT_BLOB = "select status, version, created_time, another_status from mbg_test ";
3. 缺少批量操作的方法
自定义pluginAdater后生成代码如下
@Insert({
""
})
int insertAll(@Param("records") List records);
4. 生成方法的名字不太符合我们的风格
public class CustomIntrospectedTableMyBatis3Ipl extends IntrospectedTableMyBatis3SimpleImpl {
@Override
protected void calculateXmlAttributes() {
super.calculateXmlAttributes();
setSelectByPrimaryKeyStatementId("findById");
setDeleteByPrimaryKeyStatementId("delete");
setUpdateByPrimaryKeyStatementId("update");
}
}
5. LocalDateTime支持
public class CustomJavaTypeResolver extends JavaTypeResolverDefaultImpl {
public CustomJavaTypeResolver() {
super();
typeMap.put(Types.TIMESTAMP, new JdbcTypeInformation("TIMESTAMP",
new FullyQualifiedJavaType(LocalDateTime.class.getName())));
}
}
6. 写别的方法的时候不想写select *的话就得把字段给拷贝一遍,不方便维护(表上改了,代码忘记改了或者改漏了)
自定义pluginAdater,使得把字段给提取一个变量出来,后面自己写方法的时候就可以引用了。
生成的代码:
static final String SELECT_ALL_FIELDS = "select id, status, version, created_time, another_status, msg, long_msg from mbg_test ";
7. 枚举类的支持
mybatis提供了自定义的typeHandler。在使用mybatis generator的时候指定typeHandler即可。
8. 期望可以生成一个resultMap的id"), 不用再写一遍映射关系
自定义pluginAdater,在findById方法生成后,修改一下方法的annotation加上id
扩展后自动生成代码如下
@Select({
"select",
"id, status, version, created_time, another_status, msg, long_msg",
"from mbg_test",
"where id = #{id,jdbcType=BIGINT}"
})
@Results(value = {
@Result(column="id", property="id", jdbcType=JdbcType.BIGINT, id=true),
@Result(column="status", property="status", typeHandler=IntEnumTypeHandler.class, jdbcType=JdbcType.TINYINT),
@Result(column="version", property="version", jdbcType=JdbcType.BIGINT),
@Result(column="created_time", property="createdTime", jdbcType=JdbcType.TIMESTAMP),
@Result(column="another_status", property="anotherStatus", typeHandler=IntEnumTypeHandler.class, jdbcType=JdbcType.TINYINT),
@Result(column="msg", property="msg", jdbcType=JdbcType.LONGVARCHAR),
@Result(column="long_msg", property="longMsg", jdbcType=JdbcType.LONGVARCHAR)
}, id="mbgTest")
MbgTest findById(Long id);
五.源码简单解读
1. 最外层,读取 然后挨个处理
一个context对应一个数据库
// 读取 然后挨个处理
contextsToRun = configuration.getContexts();
// methods related to code generation.
// Methods should be called in this order:
// 1.获取分析步骤(对于每个context来说有两步,1连接数据库,2分析表)
context.getIntrospectionSteps();
// 2.分析需要生成代码的相关表
context.introspectTables(callback, warnings, fullyQualifiedTableNames);
// 3.获取生成文件的步骤
context.getGenerationSteps();
// 4.获取需要生成的文件
// 每个context处理好后会把结果放到generatedJavaFiles,generatedXmlFiles,generatedKotlinFiles三个列表中
context.generateFiles(callback, generatedJavaFiles,
generatedXmlFiles, generatedKotlinFiles, warnings);
// 写文件
for (GeneratedXmlFile gxf : generatedXmlFiles) {
projects.add(gxf.getTargetProject());
writeGeneratedXmlFile(gxf, callback);
}
for (GeneratedJavaFile gjf : generatedJavaFiles) {
projects.add(gjf.getTargetProject());
writeGeneratedJavaFile(gjf, callback);
}
for (GeneratedKotlinFile gkf : generatedKotlinFiles) {
projects.add(gkf.getTargetProject());
writeGeneratedKotlinFile(gkf, callback);
}
2. 分析表introspectTables
// 1.获取类型处理器
JavaTypeResolver javaTypeResolver = ObjectFactory
.createJavaTypeResolver(this, warnings);
// 2.获取数据库分析器,分析表
DatabaseIntrospector databaseIntrospector = new DatabaseIntrospector(
this, connection.getMetaData(), javaTypeResolver, warnings);
databaseIntrospector.introspectTables(tc);
// 分析字段,包括1. 排除忽略字段,2.获取列的元数据,并根据元数据得出对应的java类型和属性名 3.应用的设置 4.处理字段相关
removeIgnoredColumns(tc, columns);
calculateExtraColumnInformation(tc, columns);
applyColumnOverrides(tc, columns);
calculateIdentityColumns(tc, columns);
// 分析表的元数据,并且得到类名,主键信息等
List introspectedTables = calculateIntrospectedTables(
tc, columns);
3. 生成文件内容generateFiles(以client生成为例)
ps:官方提供了PluginAdater,调用Plugin的地方都是我们可以插入自己逻辑的地方
// 1.获取插件列表,plugin.validate为true的才会加入
pluginAggregator = new PluginAggregator();
Plugin plugin = ObjectFactory.createPlugin(this,
pluginConfiguration);
// 2.生成interface
Interface interfaze = new Interface(type);
// 3. 生成基本方法
addDeleteByPrimaryKeyMethod(interfaze);
addInsertMethod(interfaze);
addSelectByPrimaryKeyMethod(interfaze);
addSelectAllMethod(interfaze);
addUpdateByPrimaryKeyMethod(interfaze);
// 4. 调用Plugin的方法(这个时候我们可以在plugin里面往interfaze上面挂任何我们想要的代码)
if (context.getPlugins().clientGenerated(interfaze, introspectedTable)) {
answer.add(interfaze);
}
4. 官方提供的methodGenerator
// 1.生成方法
Method method = new Method(introspectedTable.getDeleteByPrimaryKeyStatementId());
// 2.annotation
addMapperAnnotations(method);
// 3.调用plugin对应的方法(我们可以在这里修改这个method,或者阻止这个method生成)
if (context.getPlugins().clientDeleteByPrimaryKeyMethodGenerated(
method, interfaze, introspectedTable)) {
// 4.添加import
addExtraImports(interfaze);
interfaze.addImportedTypes(importedTypes);
// 5.把这个方法挂到interface上面
interfaze.addMethod(method);
}
六.定制mybatis generator的切入点---PluginAdapter
PluginAdapter提供了丰富的逻辑切入点,这些方法会在mybatis generator的各个环节被触发。而且运行的上下文环境(context),配置(properties)会被注入其中。