生成器配置文件结构
生成器配置文件generatorConfig.xml
的顶层结构如下:
- generatorConfiguration
- classPathEntry(JDBC驱动的绝对路径)
- properties(properties文件路径)
- context(生成对象的环境设置)
- property(Context作用域参数)
- jdbcConnection(JDBC连接)
- connectionFactory(JDBC连接工厂)
- commentGenerator(注释生成器)
- javaModelGenerator(实体对象生成器)
- javaClientGenerator(Mapper 接口或实现类生成器)
- sqlMapGenerator(xml 生成器)
- table(用于生成对象的表)
- javaTypeResolver(Java 类型处理器)
- plugin(插件)
生成器规则详解
context*节点
<context>
节点用于指定生成一系列对象的环境。我们可以在配置文件中配置多个节点来实现从不同数据源或采用不同生成参数生成对象。
<context>
节点最重要的属性是**targetRuntime**
,它直接决定该环境下生成的代码风格,常用的风格为 MyBatis3DynamicSql 和 MyBatis3Simple。
属性 | 描述 |
---|---|
id | 用于唯一标识指定环境。必选属性 |
defaultModelType | 指定实体对象的类型。包括三种: flat:一个表生成一个实体类; conditional:和 hierarchical 差不多,区别在于如果表只有一个主键,不会单独去生成一个主键类; hierarchical:除了生成基本类,如果表中包含主键或 BLOB 列,都会单独再生成一个主键类或BLOB类 默认为 conditional,如果 targetRuntime 为 “MyBatis3Simple”、”MyBatis3DynamicSql”或”MyBatis3Kotlin”,则该属性忽略 |
targetRuntime | 用于指定生成代码的风格(详见6.3)。 |
introspectedColumnImpl | 指定org.mybatis.generator.api.IntrospectedColumn实现类。该类可以看成是某一列的所有信息。 |
<context>
节点最重要的属性是**targetRuntime**
,它直接决定该环境下生成的代码风格(详见6.3)。
property节点
<property>
节点支持以下参数。针对 mysql 数据库,可以将定界符修改为反单引号。如果想要使用自定义的代码格式或 XML 格式,可以配置自定义实现。
属性 | 描述 |
---|---|
autoDelimitKeywords | 如果数据库关键字被作为列名使用,MBG 是否需要对其进行定界。 默认为false |
beginningDelimiter | 指定定界符的开头,默认为” |
endingDelimiter | 指定定界符的结尾,默认为” |
javaFileEncoding | 指定处理 Java 文件使用的编码 |
javaFormatter | 指定生成 Java 代码使用的格式化器。 如果自定义的话需要实现org.mybatis.generator.api.JavaFormatter 接口并提供无参构造,默认为org.mybatis.generator.api.dom.DefaultJavaFormatter |
targetJava8 | 指定生成 Java 代码使用的 JDK 版本 |
kotlinFileEncoding | 不涉及 |
kotlinFormatter | 不涉及 |
xmlFormatter | 指定生成 XML 文件使用的格式化器。如果自定义的话需要实现org.mybatis.generator.api.XmlFormatter 接口并提供无参构造,默认为org.mybatis.generator.api.dom.DefaultXmlFormatter |
jdbcConnection节点
<jdbcConnection>
节点用于指定 MBG 进行数据库交互所用的 JDBC 连接。
注意,
<jdbcConnection>
和<connectionFactory>
节点只要一个就行了。
属性 | 描述 |
---|---|
driverClass | JDBC 驱动。必选属性 |
connectionURL | JDBC URL。必选属性 |
userId | 用户名 |
password | 密码 |
包含以下子节点<property>
(0..N):用于定义 JDBC 驱动所需的一些参数,较少用到。
connectionFactory节点
<jdbcConnection>
节点用于指定和配置 MBG 进行数据库交互时获取 JDBC 连接的工厂。
注意,
<jdbcConnection>
和<connectionFactory>
节点只要一个就行了。
属性 | 描述 |
---|---|
type | 用于指定 连接工厂的类。必选属性 如果自定义的话需要实现org.mybatis.generator.api.ConnectionFactory 接口并提供无参构造,默认为org.mybatis.generator.internal.JDBCConnectionFactory |
<jdbcConnection>
的子节点为
属性 | 描述 |
---|---|
driverClass | JDBC 驱动 |
connectionURL | JDBC URL |
userId | 用户名 |
password | 密码 |
commentGenerator*节点
<commentGenerator>
节点用于指定和配置 Java 代码或 XML 文件中使用的注释生成器。
默认的注释生成器比较鸡肋,很多人都会考虑自己实现,详见6.5。
属性 | 描述 |
---|---|
type | 用于指定注释生成器的类。 如果自定义的话需要实现org.mybatis.generator.api.CommentGenerator接口并提供无参构造,默认为org.mybatis.generator.internal.DefaultCommentGenerator |
<commentGenerator>
的子节点为
Property Name | Property Values |
---|---|
suppressAllComments | 是否不生成任何注解。默认为false。 注意,前面提到过,MBG 通过注释中的@mbg.generated来判断某个元素是不是通过 MBG 生成,如果不生成注解的话,XML 的文件覆盖功能会受到影响。 |
suppressDate | 是否在注释中不包含时间。默认为false。 |
addRemarkComments | 是否在注释中包含列的注释。默认为false。 |
dateFormat | 指定时间格式。例如:yyyy-MM-dd HH:mm:ss |
javaTypeResolver节点
<javaTypeResolver>
节点用于指定和配置 Java 类型解析器。默认的解析器可能会将数据库类型 decimal 或 numberic 解析为Short、Integer、Long等 Java 类型,如果我们不希望这样解析,就需要使用到这个节点。Java 类型解析器使用默认的就行,一般不会去重写它。
属性 | 描述 |
---|---|
type | 用于指定Java 类型解析器的类。 如果自定义的话需要实现org.mybatis.generator.api.JavaTypeResolver并提供无参构造,默认为org.mybatis.generator.internal.types.JavaTypeResolverDefaultImpl,它会将数据库类型 decimal 或 numberic 解析为 Integer 的 Java 类型 |
<javaTypeResolver>
的子节点为
Property Name | Property Values |
---|---|
forceBigDecimals | 是否强制将数据库类型 decimal 或 numberic 解析为 BigDecimal 类型。默认为false,会根据数据的小数点位数和长度来决定使用 Short、Integer、Long 或 BigDecimal。 |
useJSR310Types | 是否不强制将数据库类型 date, time 和 timestamp 解析为 Date。默认为false,如果为true,解析规则将变成:date -> LocalDate,time -> LocalTime,timestamp -> LocalDateTime |
javaModelGenerator节点
<javaModelGenerator>
节点用于配置实体类生成器。实体类生成器不支持自定义。
属性 | 描述 |
---|---|
targetPackage | 指定存放生成类的包路径。必选属性 |
targetProject | 指定 targetPackage 的源文件夹。必选属性。如果该文件夹不存在,将会报错 |
<javaModelGenerator>
的子节点为
Property Name | Property Values |
---|---|
constructorBased | 是否生成包含全部参数的构造方法。 默认为false。当为true时,除了生成指定构造,还会生成对应的 resultMap。 |
enableSubPackages | 是否在targetPackage基础上生成子包。 默认为false。当为true时,会将表所在 schema 名作为子包名 |
exampleTargetPackage | 指定 Example 条件类的生成路径 默认和 targetPackage 相同 |
exampleTargetProject | 指定 exampleTargetPackage 的源文件夹 默认和 targetProject 相同 |
immutable | 如果为 true,生成的实体类将不包含 setter 方法,但会提供包含所有参数的构造。 默认为 false |
rootClass | 指定实体类需要继承的父类。 |
trimStrings | 在setter方法中是否对传入字符串进行 trim 操作 默认为 false。 |
javaClientGenerator节点
<javaClientGenerator>
节点用于指定和配置客户端类生成器。这个节点是可选的,如果不指定,则不会生成客户端类。客户端类一般指的是 Mapper 接口及 Mapper 接口的一些辅助类,例如SqlProvider 。
下面的 type 属性仅针对 MyBatis3Simple
和 MyBatis3
风格生效,而且 MyBatis3Simple
风格不支持 MIXEDMAPPER
。
属性 | 描述 |
---|---|
type | 用于指定使用客户端类生成器的类。 如果自定义的话需要实现org.mybatis.generator.codegen.AbstractJavaClientGenerator并提供无参构造,MBG 为我们提供了以下几种: 1. ANNOTATEDMAPPER:包含 Mapper 接口和 SqlProvider 辅助类,全注解,不包含 XML 文件; 2. XMLMAPPER:包含 Mapper 接口和 XML 文件,不包含注解; 3. MIXEDMAPPER:包含 Mapper 接口和 XML 文件,简单的 CRUD 使用注解,高级条件查询使用 XML 文件。 |
targetPackage | 指定存放生成类的包路径。必选属性 |
targetProject | 指定存放生成类的包路径。必选属性 |
Property Name | Property Values |
---|---|
enableSubPackages | 是否在 targetPackage 基础上生成子包。 默认为 false。当为 true 时,会将表所在 schema 名作为子包名 |
rootInterface | 指定 Mapper 接口需要实现的父接口。 |
useLegacyBuilder | 是否使用过时的SqlBuilder来构造动态语句。 默认为 false |
sqlMapGenerator节点
<sqlMapGenerator>
节点用于配置 XML 生成器,不支持自定义。
属性 | 描述 |
---|---|
targetPackage | 指定存放生成 XML 的包路径。必选属性 |
targetProject | 指定存放生成 XML 的包路径。必选属性 |
<sqlMapGenerator>
的子节点为
Property Name | Property Values |
---|---|
enableSubPackages | 是否在targetPackage基础上生成子包。 默认为false。当为true时,会将表所在 schema 名作为子包名 |
table*节点
<table>
节点用于指定需要用于生成对象的表以及配置某些生成规则。这个节点相比前面提到的,要更加复杂一些。<table>
节点支持的属性很多,一般保持默认就可以了。
属性 | 描述 |
---|---|
tableName | 需要生成对象的表名。必选属性。允许使用 SQL 通配符,例如:demo_%。 |
schema | 指定数据库 schema。允许使用 SQL 通配符。 |
catalog | 指定数据库 catalog |
alias | 指定查询时字段别名前缀。 如果指定,生成的 select 语句将使用alias_actualColumnName的别名 |
domainObjectName | 指定实体类的类名。默认情况下使用驼峰命名规则。 |
mapperName | 指定 Mapper 接口名。默认为实体类名+Mapper。 |
sqlProviderName | 指定 SqlProvider 接口名。默认为实体类名+SqlProvider。 |
enableInsert enableSelectByPrimaryKey enableSelectByExample enableUpdateByPrimaryKey enableDeleteByPrimaryKey enableDeleteByExample enableCountByExample enableUpdateByExample |
| 是否生成指定语句。默认为true。 |
| selectByPrimaryKeyQueryId
selectByExampleQueryId | 如果指定,在select 语句中将添加 ‘value’ as QUERYID |
| modelType | 指定实体对象的类型。context节点中已介绍过了 |
| escapeWildcards | 当 schema 或 tableName 包含 SQL 通配符,在搜素列时是否对其进行转义 |
| delimitIdentifiers | 是否在 SQL 中对表名使用定界符并且使用确定的表名大小写。默认为false。 |
| delimitAllColumns | 是否在 SQL 中对所有列名都添加定界符。默认为false。 |
<table>
的子节点如下:
(0..N) (0 or 1) (0 or 1) (0 or 1) (0..N) (0..N) (0..N)
这几个子节点中,常用到的是
Property Name | Property Values |
---|---|
constructorBased | 是否生成包含全部参数的构造方法。默认为false。当为true时,除了生成指定构造,还会生成对应的 resultMap。 |
ignoreQualifiersAtRuntime | 在生成的 SQL 中,表名前是否不添加 schema 或 catalog。默认为 false |
immutable | 如果为 true,生成的实体类将不包含 setter 方法,但会提供包含所有参数的构造。默认为 false。 |
modelOnly | 是否只生成实体类。默认为 false。 |
rootClass | 指定实体类需要继承的父类。 |
rootInterface | 指定 Mapper 接口需要实现的父接口。 |
runtimeCatalog | 指定 SQL 中使用的 catalog |
runtimeSchema | 指定 SQL 中使用的 schema |
runtimeTableName | 指定 SQL 中使用的 tableName |
selectAllOrderByClause | 指定selectAll方法中加入order by ‘value’ |
trimStrings | 实体类的 setter 方法中是否对传入字符串进行 trim 操作。默认为 false。 |
useActualColumnNames | 是否直接使用表名作为实体类类名。默认为false。 |
useColumnIndexes | 是否在 resultMap 中使用索引而不使用列名进行映射 |
useCompoundPropertyNames | 是否将“列名+列注释”作为实体类的属性名 |
domainObjectRenamingRule/columnRenamingRule<domainObjectRenamingRule>
节点一般用于重命名实体类类名。例如,在没有指定 domainObjectName
的情况下,demo_employee 的表将生成实体类 DemoEmloyee,但我希望去掉前面的 Demo 前缀,则可以这样处理:
<table tableName="demo_%" >
<!-- replaceString属性可以省略 -->
<domainObjectRenamingRule searchString="^Demo" replaceString=""/>
</table>
另一个子节点<columnRenamingRule>
也是相同的用法。
<table tableName="demo_%" >
<columnRenamingRule searchString="^Employee_" replaceString="" />
</table>
gnoreColumnsByRegex/ignoreColumn<ignoreColumnsByRegex>
和<ignoreColumn>
节点用于告诉 MBG 生成代码时忽略某些列。使用方法如下。
<table tableName="Foo">
<ignoreColumnsByRegex pattern="(?i)col.*">
<except column="col01"/>
<except column="col13"/>
</ignoreColumnsByRegex>
</table>
plugin*节点
<plugin>
节点用于定义和配置插件。这个节点只有一个 type 属性,用于指定使用哪个插件,并通过子节点 property 来为这个插件设置参数。
官方插件
M官方为我们提供了许多好用的插件,如下:
插件 | 描述 |
---|---|
org.mybatis.generator.plugins.SerializablePlugin | 用于在实体类中实现java.io.Serializable接口 |
org.mybatis.generator.plugins.ToStringPlugin | 用于在实体类中添加 toString 方法 |
org.mybatis.generator.plugins.EqualsHashCodePlugin | 用于在实体类中添加 equals 和 hashCode 方法。 |
org.mybatis.generator.plugins.UnmergeableXmlMappersPlugin | 用于指定不合并 XML 文件,这时 MBG 将 采用处理 Java 文件的方式来处理 XML 文件 |
org.mybatis.generator.plugins.CachePlugin | 用于在 xml 文件中加入cache节点 |
org.mybatis.generator.plugins.CaseInsensitiveLikePlugin | 用于在 Example 类中生成不区分大小写的Like |
org.mybatis.generator.plugins.dsql.DisableDeletePlugin | 禁用 MyBatisDynamicSQLV2 风格的所有删除方法 |
org.mybatis.generator.plugins.dsql.DisableInsertPlugin | 禁用 MyBatisDynamicSQLV2 风格的所有插入方法 |
org.mybatis.generator.plugins.dsql.DisableUpdatePlugin | 禁用 MyBatisDynamicSQLV2 风格的所有更新方法 |
org.mybatis.generator.plugins.FluentBuilderMethodsPlugin | 用于在实体类中添加MyDomainClass withValue(Object v)方法。通过它可以实现如下赋值方式: new Employee().withAddress(“北京”).withDeleted(false).withName(“zzs001”); |
org.mybatis.generator.plugins.MapperAnnotationPlugin | 用于在 Mapper 接口中添加@Mapper接口 |
org.mybatis.generator.plugins.MapperConfigPlugin | 用于生成 Mybatis 的主配置文件 MapperConfig |
org.mybatis.generator.plugins.RenameExampleClassPlugin | 用于重命名 Example 类 |
org.mybatis.generator.plugins.RowBoundsPlugin | 用于在 Mapper 接口的 selectByExample 方法参数中加入 RowBounds 参数,用于支持分页 |
org.mybatis.generator.plugins.VirtualPrimaryKeyPlugin | 用于指定表的主键 |
插件的配置方式非常简单,如下:
<!-- 插件 -->
<plugin type="org.mybatis.generator.plugins.EqualsHashCodePlugin">
<property name="useEqualsHashCodeFromRoot" value="true"/>
</plugin>
<plugin type="org.mybatis.generator.plugins.ToStringPlugin">
<property name="useToStringFromRoot" value="true"/>
</plugin>
运行 Java 程序,可以看到实体类中生成类 toString 、hashCode 和 equals 方法。
自定义插件
如果自定义的话,需要实现org.mybatis.generator.api.Plugin接口,并提供无参构造,当然,这里推荐继承org.mybatis.generator.api.PluginAdapter来避免重写太多方法。下面举个例子来讲解自定义插件的使用。
例如对于menu表自动生成的实体名字是 Menu,如果想命名为 MenuDomain,而生成的 Mapper 命名为 MenuDAO。为了实现这种需求,我们可以先定义一个插件,如下:
public class RenameFilePlugin extends PluginAdapter {
@Override
public boolean validate(List<String> warnings) {
return true;
}
@Override
public void initialized(IntrospectedTable introspectedTable) {
// 更改实体类名称,例如:cn.zzs.mybatis.entity.Menu => cn.zzs.mybatis.entity.MenuDomain
String oldType = introspectedTable.getBaseRecordType();
introspectedTable.setBaseRecordType(oldType + "Domain");
// 更改Mapper名称
String mapperType = introspectedTable.getMyBatis3JavaMapperType();
introspectedTable.setMyBatis3JavaMapperType(mapperType.replace("Mapper", "DAO"));
}
}
然后将插件配置:
<plugin type="cn.zzs.mybatis.plugin.RenameFilePlugin"></plugin>
下一章中我们将使用一个自定义的插件给生成的代码添加额外的注解