在 MyBatis Generator 的 xml 配置文件的根元素 generationConfiguration 中,context 是核心元素,用于配置生成一组对象的环境。

前文请参考:解析 MyBatis Generator 的使用及配置

配置 context 核心元素

在 generationConfiguration 的子元素中,context 是核心元素,用于配置生成一组对象的环境。元素 context 有 4 个属性可供配置:

  • id,必填,上下文 id,用于在生成错误时提示;保证多个 context 的 id 不重复就行。
  • targetRuntime,选填项,这个配置会影响生成的 dao 和 mapper.xml 的内容。常见值为:
    1. MyBatis3,默认值,生成基于 MyBatis 3.x 以上版本的内容,包括很多类似 XxxByExample 的 dao 方法。
    2. MyBatis3Simple,类似 MyBatis3,只是不生成类似 XxxByExample 的 dao 方法,一般选择不生成这些繁杂的方法
    3. 还有其它可配置的值,详情见 官网
  • defaultModelType,选填项,用于指定生成对象的样式。其值为:
    1. conditional,默认值,类似于 hierarchical。区别是,不会为只有一个字段的数据库表生成一个单独的类。
    2. hierarchical,主键生成一个 XxxKey 对象(key class),Blob 等字段单独生成一个对象,其它简单属性在一个对象中(record class)。
    3. flat,所有字段(主键、blob 等)全部生成在一个对象中。
  • introspectedColumnImpl,选填项,类全限定名,用于 扩展 MBG

示例配置如下:

1
2
3
<context id="MySqlContext" targetRuntime="MyBatis3" defaultModelType="flat">
...
</context>

context 的子元素

元素 context 中,有多个子元素需要配置。同样的,context 的子元素必须按照下面给出的次数和顺序进行配置:

  1. property (0…N)
  2. plugin (0…N)
  3. commentGenerator (0 or 1)
  4. connectionFactoryjdbcConnection,二选一进行配置
  5. javaTypeResolver (0 or 1)
  6. javaModelGenerator(有且仅有 1 次)
  7. sqlMapGenerator (0 or 1)
  8. javaClientGenerator (0 or 1)
  9. table (1…N)

可以看出,javaModelGenerator、table 以及 connection 元素的配置是必需的。

property 元素

用于为代码生成指定属性,或为其它元素指定属性。可以配置零个或多个,常见的 property 配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<!-- 自动识别数据库关键字,默认为 false,一般保留默认值,
遇到数据库关键字(Java关键字)时,按照 table 元素中 columnOverride 属性的配置进行覆盖。
如果设置为 true, 则需按照 SqlReservedWords 中定义的关键字列表,对关键字进行定界(分隔)。
定界符(分隔符)参见 beginningDelimiter 和 endingDelimiter 的设置 -->
<property name="autoDelimitKeywords" value="false"/>

<!-- beginningDelimiter 和 endingDelimiter,定界符(分隔符),
指明用于标记数据库关键字的符号,默认为为双引号 (");
在 oracle 中是双引号 ("),在 MySQL 中需配置为反引号 (`) -->
<property name="beginningDelimiter" value="`"/>
<property name="endingDelimiter" value="`"/>

<!-- 生成的 Java 文件的编码 -->
<property name="JavaFileEncoding" value="UTF-8"/>

<!-- 格式化 Java 代码 -->
<property name="javaFormatter" value="org.mybatis.generator.api.dom.DefaultJavaFormatter"/>
<!-- 格式化 XML 代码 -->
<property name="xmlFormatter" value="org.mybatis.generator.api.dom.DefaultXmlFormatter"/>

注:SqlReservedWords 关键字列表

plugin 元素

配置插件,可以有零个或多个,常见的 plugin 配置有:

1
2
3
4
5
6
<!-- 使生成的 Model 实现 Serializable 接口  -->
<plugin type="org.mybatis.generator.plugins.SerializablePlugin"/>
<!-- 为生成的 Model 覆写 toString() 方法 -->
<plugin type="org.mybatis.generator.plugins.ToStringPlugin"/>
<!-- 为生成的 Model 覆写 equals() 和 hashCode() 方法 -->
<plugin type="org.mybatis.generator.plugins.EqualsHashCodePlugin"/>

commentGenerator 元素

可以配置 0 个或 1 个,用来配置生成的注释,默认是生成注释的,并且会在注释中添加时间等信息。如果想沿用默认的注释配置的话,可以不用配置 commentGenerator 元素。否则,可以进行如下配置:

1
2
3
4
5
6
7
8
9
10
11
<commentGenerator>
<!-- 不生成所有注释,默认为 false -->
<property name="suppressAllComments" value="true"/>

<!-- 生成的注释中不包含时间信息,默认为 false -->
<property name="suppressDate" value="true"/>
<!-- 生成的注释中,时间的显示格式 -->
<property name="dateFormat" value="yyyy/MM/dd"/>
<!-- 是否添加数据库表中字段的注释,默认为 false -->
<property name="addRemarkComments" value="true"/>
</commentGenerator>

当然,你也可以 自定注释生成器

jdbcConnection 元素

配置数据库连接,具体如下:

1
2
3
4
5
6
7
8
9
<!--  配置数据库连接  -->
<jdbcConnection driverClass="${jdbc.driverClass}"
connectionURL="${jdbc.connectionURL}"
userId="${jdbc.userId}"
password="${jdbc.password}">

<!-- 若为 8.0 版本以上的 mysql-connector-java 驱动,需要设置 nullCatalogMeansCurrent = true -->
<!-- <property name="nullCatalogMeansCurrent" value="true"/> -->
</jdbcConnection>

其中,${propertyKey} 里面是引用的外部配置文件中的 propertyValue:

mbgproperties2.png

你也可以写死,那么就不用在 <properties resource=""/> 中引入此文件了。

这里面值得注意的是 <property name="nullCatalogMeansCurrent" value="true"/> ,当 mysql-connector-java 驱动在 8.0 版本以上时,如果不配置这一项为 true,会不生成指定数据库中表的 Mapper。具体原因可参考文章:MyBatis Generator踩坑与自救

javaTypeResolver 元素

可以配置 0 或 1 个,用来配置 JDBC 到 Java 中的类型转换规则,如果不进行配置,则使用默认的转换规则,默认使用 org.mybatis.generator.internal.types.JavaTypeResolverDefaultImpl

就算要配置,也只能配置 BigDecimal 和时间类型的转换:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<javaTypeResolver>
<!-- 是否强制使用 BigDecimal;
默认为 false,把 JDBC 的 DECIMAL 和 NUMERIC 类型解析为 Integer;
设置为 true 时,把 JDBC 的 DECIMAL 和 NUMERIC 类型解析为 java.math.BigDecimal 。 -->
<property name="forceBigDecimals" value="true"/>

<!-- 设置时间类型的转换,
默认 false,将所有 JDBC 的时间类型解析为 java.util.Date;
设置为 true 时,将 JDBC 的时间类型按如下规则解析:
DATE -> java.time.LocalDate
TIME -> java.time.LocalTime
TIMESTAMP -> java.time.LocalDateTime
TIME_WITH_TIMEZONE -> java.time.OffsetTime
TIMESTAMP_WITH_TIMEZONE -> java.time.OffsetDateTime
-->
<property name="useJSR310Types" value="true"/>
</javaTypeResolver>

javaModelGenerator 元素

Java 模型生成器,有且仅能配置一个,负责 key 类(见 context 元素的 defaultModelType 属性)、Java Bean 实体类、查询类的生成。

元素 javaModelGenerator 有两个属性:

  • targetPackage:生成的类要放的包,具体的包受子元素 enableSubPackages 影响;
  • targetProject:目标项目,指定一个已存在的目录。(targetProject 的路径配置,对于不同的 MBG 启动方式会有一些区别,详情见 第三节:运行 MyBatis-Generator

在 javaModelGenerator 元素中还可以配置多个 property 子元素,具体代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<!--  配置 Java 模型生成器 -->
<javaModelGenerator targetPackage="deecyn.shop_02.mbg.model" targetProject="src/main/java">
<!-- 自动为每一个生成的类创建一个构造方法,构造方法包含了所有的 field,而不是使用 setter;
默认值为 false -->
<property name="constructorBased" value="false"/>

<!-- 在 targetPackage 的基础上,根据数据库的 schema 再生成一层 package,
最终生成的类放在这个package下;默认为false -->
<property name="enableSubPackages" value="false"/>

<!-- 是否创建一个不可变的类:如果为true,那么 MBG 生成的类会没有 setter 方法,
采用构造函数的方式来接收和设置每个字段的值,此时会忽略 constructorBased 属性的设置;
默认值为 false -->
<property name="immutable" value="false"/>

<!-- 设置在 getter 方法中,是否对 String 类型的字段调用 trim() 方法;默认为 false -->
<property name="trimStrings" value="true"/>
</javaModelGenerator>

sqlMapGenerator 元素

可以配置 0 或 1 个,生成 SQL Map 的 xml 文件生成器。在 MyBatis3 之后,我们可以使用 mapper.xml 文件 + Mapper 接口,或者只使用 Mapper 接口 + Annotation;所以,如果 javaClientGenerator 元素中配置了需要生成 xml 的话,这个元素就必须配置。

该元素有 targetPackage 和 targetProject 两个属性,原理与 javaModelGenerator 元素的相同,只不过这里指的是 resource 目录下存放 mapper.xml 文件的路径。具体代码如下:

1
2
3
4
5
<!-- SQL Map 的 xml 文件生成器 -->
<sqlMapGenerator targetPackage="mbg-mapper" targetProject="src/main/resources">
<!-- 同 javaModelGenerator 元素中的配置 -->
<property name="enableSubPackages" value="false"/>
</sqlMapGenerator>

javaClientGenerator 元素

可以配置 0 或 1 个,用于配置关于 Mapper 接口的生成,如果没有配置该元素,那么默认不会生成 Mapper 接口。

元素 javaClientGenerator 有 3 个属性,其中 targetPackage 和 targetProject 属性的配置与 javaModelGenerator 元素的原理相同,只不过这里指的是 java 目录下存放 Mapper 接口的路径。关于 type 属性,有 3 个可选值:

  • ANNOTATEDMAPPER,按照使用 Mapper 接口 + Annotation 的方式生成文件,SQL 生成在对应的 Annotation 中,不会生成 xml 文件。
  • MIXEDMAPPER,使用混合配置,会生成 Mapper 接口,并适当添加合适的 Annotation,也会有 SQL 生成在 XML 文件中。
  • XMLMAPPER,会生成 Mapper 接口,接口完全依赖 XML 文件。

注意,如果 context 元素的 defaultModelType 属性设置为 MyBatis3Simple,那么就只支持 ANNOTATEDMAPPER 和 XMLMAPPER 的方式。一般建议将 type 设置成 XMLMAPPER

1
2
3
4
5
6
<!--  关于 Mapper 接口的生成 -->
<javaClientGenerator type="XMLMAPPER" targetPackage="deecyn.shop_02.mbg.mapper"
targetProject="src/main/java">
<!-- 同 javaModelGenerator 元素中的配置 -->
<property name="enableSubPackages" value="false"/>
</javaClientGenerator>

table 元素

一个 table 元素对应一张数据库表,如果想同时为多张表生成代码,需要配置多个 table 元素;或者可以将 tableName 设置为 % 来为全部表生成代码。

元素 table 除开一个必须的属性 tableName(数据库表名称)需要设置外,还有很多可选的属性,部分属性如下:

  1. schema,数据库的 schema;
  2. catalog,数据库的 catalog;
  3. domainObjectName:生成的 domain 类的名字,如果不设置,直接使用表名的驼峰命名作为 domain 类的名字;可以设置为 somepackage.domainName,那么会自动把 domainName 类再放到 somepackage 包里面;
  4. enableSelectByExample,默认 true,MyBatis3Simple 为 false,指定是否生成动态查询语句;
  5. enableUpdateByPrimaryKey,默认 true,指定是否生成按照主键修改对象的语句(即 update);
  6. enableDeleteByExample,默认 true,MyBatis3Simple 为 false,指定是否生成动态删除语句;
  7. enableCountByExample,默认 true,MyBatis3Simple 为 false,指定是否生成动态查询总条数语句(用于分页的总条数查询);
  8. enableUpdateByExample,默认 true,MyBatis3Simple为false,指定是否生成动态修改语句(只修改对象中不为空的属性);
  9. modelType,参考 context 元素的 defaultModelType,相当于对其进行覆盖。

此外,table 元素中还可以配置多个 property 和 columnOverride 等子元素。示例代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<!-- 配置需要生成代码的数据库表 -->
<table tableName="pms_brand" domainObjectName="PmsBrand"
enableCountByExample="false" enableUpdateByExample="false"
enableDeleteByExample="false" enableSelectByExample="false"
selectByExampleQueryId="false">

<!-- 指定是否只生成 domain 类,默认为 false;
如果设置为 true,则只生成 domain 类,如果还配置了sqlMapGenerator,那么
在 mapper.xml 文件中,只生成 resultMap 元素 -->
<property name="modelOnly" value="false"/>

<!-- 默认为 false;如果设置为 true,生成的 model 类会直接使用 column 本身的名字,而不会再使用驼峰命名方法。比如 CREATE_DATE,生成的属性名字就是 CREATE_DATE,而不会是 createDate -->
<property name="useActualColumnNames" value="false"/>

<!-- 生成主键的方法,如果设置了该元素,MBG 会在生成的 <insert> 元素中生成一条正确的 <selectKey> 元素 -->
<generatedKey column="id" sqlStatement="MySql" identity="true"/>

<!-- 用来修改表中某个列的属性,MBG 会根据修改后的配置来生成 domain 的属性;
column:要重新设置的列名;一个 table 元素中可以定义多个 columnOverride 元素哈 -->
<columnOverride column="show_status">
<!-- 使用 property 属性来指定列要生成的属性名称 -->
<property name="property" value="showStatus"/>

<!-- javaType 用于指定生成的 domain 的属性类型,使用类型的全限定名-->
<property name="javaType" value="java.lang.Integer"/>

<!-- jdbcType用于指定该列的JDBC类型
<property name="jdbcType" value=""/>
-->
</columnOverride>
</table>

推荐阅读:解析 MyBatis Generator 的使用及配置