XML配置详解

MBG 具有丰富的配置可供使用,这些配置需要以 XML 形式的标签和属性来实现,所以本节就对 MBG 的 XML 配置进行详细介绍。如果从来没有接触过 MBG,并且想在学习过程中尝试 XML 中的各种配置,建议先阅读 5.2 节提供的一个简单配置和 5.3 节中关于如何运行 MBG 的内容,当可以正常运行 MBG 时,再从 5.1 节看起。如果使用过 MBG,也可以直接从 5.1 节开始阅读。

首先按照 MBG 的要求添加 XML 的文件头。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
        PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
        "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">

这个文件头中的 mybatis-generator-config_1_0.dtd 用于定义该配置文件中所有标签和属性的用法及限制,在文件头之后,需要写上 XML 文件的根节点 generatorConfiguration。

<generatorConfiguration>
<!-- 具体配置内容 -->
</generatorConfiguration>

上面这两部分内容是 MBG 必备的基本信息,后面是 MBG 中的自定义配置部分。下面先介绍 generatorConfiguration 标签下的 3 个子级标签,分别是 properties、classPathEntry 和 context。在配置这 3 个标签的时候,必须注意它们的顺序,要和这里列举的顺序一致,在后面列举其他标签的时候,也必须严格按照列举这些标签的顺序进行配置。

第一个是 properties 标签。这个标签用来指定外部的属性元素,最多可以配置 1 个,也可以不配置。

properties 标签用于指定一个需要在配置中解析使用的外部属性文件,引入属性文件后,可以在配置中使用 ${property} 这种形式的引用,通过这种方式引用属性文件中的属性值,对于后面需要配置的 JDBC 信息会很有用。

properties 标签包含 resource 和 url 两个属性,只能使用其中一个属性来指定,同时出现则会报错。

第二个是 classPathEntry 标签。这个标签可以配置多个,也可以不配置。classPathEntry 标签最常见的用法是通过属性 location 指定驱动的路径,代码如下。

<classPathEntry location="E:\mysql\mysql-connector-java-5.1.29.jar"/>

这个标签还可以用于 5.1.6 节中,通过使用这种方式指定 rootClass 属性配置类所在的 jar 包。

第三个是 context 标签。这个标签是要重点讲解的,该标签至少配置 1 个,可以配置多个。

context 标签用于指定生成一组对象的环境。例如指定要连接的数据库,要生成对象的类型和要处理的数据库中的表。运行 MBG 的时候还可以指定要运行的 context。

context 标签只有一个必选属性 id,用来唯一确定该标签,该 id 属性可以在运行 MBG 时使用。此外还有几个可选属性。

  • defaultModelType:这个属性很重要,定义了 MBG 如何生成实体类。该属性有以下可选值。

    • conditional:默认值,和下面的 hierarchical 类似,如果一个表的主键只有一个字段,那么不会为该字段生成单独的实体类,而是会将该字段合并到基本实体类中。

    • flat:该模型只为每张表生成一个实体类。这个实体类包含表中的所有字段。这种模型最简单,推荐使用。

    • hierarchical:如果表有主键,那么该模型会产生一个单独的主键实体类,如果表还有 BLOB 字段,则会为表生成一个包含所有 BLOB 字段的单独的实体类,然后为所有其他的字段另外生成一个单独的实体类。MBG 会在所有生成的实体类之间维护一个继承关系。

  • targetRuntime:此属性用于指定生成的代码的运行时环境,支持以下可选值。

    • MyBatis3:默认值。

    • MyBatis3Simple:这种情况不会生成与 Example 相关的方法。

  • introspectedColumnImpl:该参数可以指定扩展 org.mybatis.generator.api.Introspected Column 类的实现类。

一般情况下,使用如下配置即可。

<context id="Mysql" defaultModelType="flat">

如果不希望生成和 Example 查询有关的内容,则可以按照如下方法进行配置。

<context id="Mysql" targetRuntime="MyBatis3Simple" defaultModelType="flat">

MBG 配置中的其他几个标签基本上都是 context 的子标签,这些子标签(有严格的配置顺序,后面括号中的内容为这些标签可以配置的个数)包括以下几个。

  • property(0 个或多个)

  • plugin(0 个或多个)

  • commentGenerator(0 个或 1 个)

  • jdbcConnection(1 个)

  • javaTypeResolver(0 个或 1 个)

  • javaModelGenerator(1 个)

  • sqlMapGenerator(0 个或 1 个)

  • javaClientGenerator(0 个或 1 个)

  • table(1 个或多个)

下面逐条介绍这些重要的标签。

property标签

在开始介绍 property 标签前,先来了解一下数据库中的分隔符。

举一个简单的例子,假设数据库中有一个表,名为 user info,注意这个名字,user 和 info 中间存在一个空格。如果直接写如下查询,在数据库执行这个查询时会报错。

select * from user info

可能会提示 user 表不存在或者 user 附近有语法错误,这种情况下该怎么写 user info 表呢?

这时就会用到分隔符,在 MySQL 中可以使用反单引号 ` 作为分隔符,例如 `user info`,在 SQL Server 中则是 [user info]。通过分隔符可以将其中的内容作为一个整体的字符串进行处理,当 SQL 中有数据库关键字时,使用反单引号括住关键字,可以避免数据库产生错误。

这里之所以先介绍分隔符,就是因为 property 标签中包含了以下 3 个和分隔符相关的属性。

  • autoDelimitKeywords

  • beginningDelimiter

  • endingDelimiter

从名字可以看出,第一个是自动给关键字添加分隔符的属性。MBG 中维护了一个关键字列表,当数据库的字段或表与这些关键字一样时,MBG 会自动给这些字段或表添加分隔符。关键字列表可以查看 MBG 中的 org.mybatis.generator.internal.db.SqlReservedWords 类。

后面两个属性很简单,一个是配置前置分隔符的属性,一个是配置后置分隔符的属性。在 MySQL 中,两个分隔符都是 `,在 SQL Server 中分别为 “[” 和 “]”,MySQL 中的 property 配置写法如下。

<context id="Mysql" targetRuntime="MyBatis3Simple" defaultModelType="flat">
    <property name="autoDelimitKeywords" value="true"/>
    <property name="beginningDelimiter" value="`"/>
    <property name="endingDelimiter" value="`"/>
</context>

除了上面 3 个和分隔符相关的属性外,还有以下 3 个属性。

  • javaFileEncoding

  • javaFormatter

  • xmlFormatter

属性 javaFileEncoding 设置要使用的 Java 文件的编码,例如 GBK 或 UTF-8。默认使用当前运行环境的编码。后面两个 Formatter 相关的属性并不常用,这里不做详细介绍。

plugin标签

plugin 标签可以配置 0 个或者多个,个数不受限制。

plugin 标签用来定义一个插件,用于扩展或修改通过 MBG 生成的代码。该插件将按在配置中配置的顺序执行。MBG 插件使用的情况并不多,如果对开发插件有兴趣,可以参考 MBG 文档,或者参考下面要介绍的缓存插件的例子,这个例子包含在 MBG 插件中。

下面要介绍的缓存插件的全限定名称为 org.mybatis.generator.plugins.CachePlugin。

这个插件可以在生成的 SQL XML 映射文件中增加一个 cache 标签。只有当 targetRuntime 为 MyBatis3 时,该插件才有效。

该插件接受下列可选属性。

  • cache_eviction

  • cache_flushInterval

  • cache_readOnly

  • cache_size

  • cache_type

配置方法如下。

<plugin type="org.mybatis.generator.plugins.CachePlugin">
    <property name="cache_eviction" value="LRU" />
    <property name="cache_size" value="1024" />
</plugin>

增加这个配置后,生成的 Mapper.xml 文件中会增加如下的缓存相关配置。

<cache eviction="LRU" size="1024">
<!--
    WARNING - @mbggenerated
    This element is automatically generated by MyBatis Generator,do not modify.
-->
</cache>

这一节主要介绍如何配置插件,和缓存相关的内容会在第7章中介绍。

在 MBG 默认包含的插件中,除了缓存插件外,还有序列化插件、RowBounds 插件、ToString 插件等,关于这些插件的介绍可以查看 MBG 文档。查看英文文档: http://www.mybatis.org/generator/reference/plugins.html 。查看中文文档: http://mbg.cndocs.tk/reference/plugins.html

commentGenerator标签

该标签用来配置如何生成注释信息,最多可以配置 1 个。

该标签有一个可选属性 type,可以指定用户的实现类,该类需要实现 org.mybatis.generator.api.CommentGenerator 接口,而且必有一个默认空的构造方法。type 属性接收默认的特殊值 DEFAULT,使用默认的实现类 org.mybatis.generator.internal.DefaultCommentGenerator。

默认的实现类中提供了三个可选属性,需要通过 property 属性进行配置。

  • suppressAllComments:阻止生成注释,默认为 false。

  • suppressDate:阻止生成的注释包含时间戳,默认为 false。

  • addRemarkComments:注释是否添加数据库表的备注信息,默认为 false。

一般情况下,由于 MBG 生成的注释信息没有任何价值,而且有时间戳的情况下每次生成的注释都不一样,使用版本控制的时候每次都会提交,因而一般情况下都会屏蔽注释信息,可以如下配置。

<commentGenerator>
    <property name="suppressDate" value="true"/>
    <property name="addRemarkComments" value="true"/>
</commentGenerator>

在数据库表字段包含备注信息的情况下生成的 Java 对象代码的注释如下。

/**
* Database Column Remarks:
*   角色名
*
* This field was generated by MyBatis Generator.
* This field corresponds to the database column sys_role.role_name
*
* @mbggenerated
*/
private String roleName;

如果对上面的注释不满意或者想实现自己的注释形式,可以实现 CommentGenerator,参考 MBG 中的 DefaultCommentGenerator 即可。这里提供一个简单例子供参考,假设实现类为 tk.mybatis.generator.MyCommentGenerator,代码如下。

package tk.mybatis.generator;

import static org.mybatis.generator.internal.util.StringUtility.isTrue;

import java.util.Properties;

import org.mybatis.generator.api.IntrospectedColumn;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.dom.java.Field;
import org.mybatis.generator.config.PropertyRegistry;
import org.mybatis.generator.internal.DefaultCommentGenerator;
import org.mybatis.generator.internal.util.StringUtility;

/**
 * 自己实现的注释生成器
 */
public class MyCommentGenerator extends DefaultCommentGenerator {
	/**
	 * 由于默认实现类中的可配参数都没有提供给子类可以访问的方法,这里要定义一遍
	 */
    private boolean suppressAllComments;

    /**
     * 同上
     */
    private boolean addRemarkComments;

    /**
     * 设置用户配置的参数
     */
    public void addConfigurationProperties(Properties properties) {
    	//先调用父类方法保证父类方法可以正常使用
    	super.addConfigurationProperties(properties);
    	//获取 suppressAllComments 参数值
        suppressAllComments = isTrue(properties
        		.getProperty(PropertyRegistry.COMMENT_GENERATOR_SUPPRESS_ALL_COMMENTS));
        //获取 addRemarkComments 参数值
        addRemarkComments = isTrue(properties
        		.getProperty(PropertyRegistry.COMMENT_GENERATOR_ADD_REMARK_COMMENTS));
    }

    /**
     * 给字段添加注释信息
     */
	public void addFieldComment(Field field,
            IntrospectedTable introspectedTable,
            IntrospectedColumn introspectedColumn) {
		//如果阻止生成所有注释,直接返回
        if (suppressAllComments) {
            return;
        }
        //文档注释开始
        field.addJavaDocLine("/**");
        //获取数据库字段的备注信息
        String remarks = introspectedColumn.getRemarks();
        //根据参数和备注信息判断是否添加备注信息
        if (addRemarkComments && StringUtility.stringHasValue(remarks)) {
            String[] remarkLines = remarks.split(System.getProperty("line.separator"));
            for (String remarkLine : remarkLines) {
                field.addJavaDocLine(" * " + remarkLine);
            }
        }
        //由于 Java 对象名和数据库字段名可能不一样,注释中保留数据库字段名
        field.addJavaDocLine(" * " + introspectedColumn.getActualColumnName());
        field.addJavaDocLine(" */");
    }
}

有了自己的注释生成器后,可以在配置文件中如下进行配置。

<commentGenerator type="tk.mybatis.generator.MyCommentGenerator">
    <property name="suppressDate" value="true"/>
    <property name="addRemarkComments" value="true"/>
</commentGenerator>

重写注释后,生成代码中的注释如下。

/**
* 角色名
* role_name
*/
private String roleName;

大家可以参考上面的例子编写自己的注释生成器。

MBG 是通过 JDBC 的 DatabaseMetaData 方式来获取数据库表和字段的备注信息的,大多数的 JDBC 驱动并不支持,常用数据库中 MySQL 支持,SQL Server 不支持。Oracle 特殊配置后可以支持,配置方式见下一节关于 jdbcConnection 标签的介绍。

jdbcConnection标签

jdbcConnection 用于指定 MBG 要连接的数据库信息,该标签必选,并且只能有一个。

配置该标签需要注意,如果 JDBC 驱动不在 classpath 下,就要通过 classPathEntry 标签引入 jar 包,这里推荐将 jar 包放到 classpath 下,或者参考前面 classPathEntry 配置 JDBC 驱动的方法。

该标签有两个必选属性。

  • driverClass:访问数据库的 JDBC 驱动程序的完全限定类名。

  • connectionURL:访问数据库的 JDBC 连接 URL。

该标签还有两个可选属性。

  • userId:访问数据库的用户 ID。

  • password:访问数据库的密码。

此外,该标签还可以接受多个 property 子标签,这里配置的 property 属性都会添加到 JDBC 驱动的属性中(使用 proprety 标签的 name 属性反射赋值)。

这个标签配置起来非常容易,基本配置如下。

<jdbcConnection driverClass="com.mysql.jdbc.Driver"
                connectionURL="jdbc:mysql://localhost:3306/mybatis2?characterEncoding=utf8"
                userId="root"
                password="root">
</jdbcConnection>

在上一节提醒过,Oracle 可以通过特殊配置使 JDBC 方式能够获取到列的注释信息,配置方式如下。

<jdbcConnection driverClass="com.mysql.jdbc.Driver"
                connectionURL="jdbc:mysql://localhost:3306/mybatis2?characterEncoding=utf8"
                userId="root"
                password="root">
    <property name="remarksReporting" value="true" />
</jdbcConnection>

这种方式就是通过 property 标签配置了 Oracle 的 remarksReporting 属性,使得 JDBC 方式可以获取注释信息。

javaTypeResolver标签

该标签的配置用来指定 JDBC 类型和 Java 类型如何转换,最多可以配置一个。

该标签提供了一个可选的属性 type。另外,和 commentGenerator 类似,该标签提供了默认的实现 DEFAULT,一般情况下使用默认即可,需要特殊处理的情况可以通过其他标签配置来解决,不建议修改该属性。

该属性还有一个可以配置的 property 标签,可以配置的属性为 forceBigDecimals,该属性可以控制是否强制将 DECIMAL 和 NUMERIC 类型的 JDBC 字段转换为 Java 类型的 java.math.BigDecimal,默认值为 false,一般不需要配置。

默认情况下的转换规则如下。

  • 如果精度 >0 或者长度 >18,就使用 java.math.BigDecimal。

  • 如果精度 =0 并且 10 <= 长度 <= 18,就使用 java.lang.Long。

  • 如果精度 =0 并且 5 <= 长度 <= 9,就使用 java.lang.Integer。

  • 如果精度 =0 并且长度 <5,就使用 java.lang.Short。

如果将 forceBigDecimals 设置为 true,那么一定会使用 java.math.BigDecimal 类型。

javaTypeResolver 标签配置如下。

<javaTypeResolver>
    <property name="forceBigDecimals" value="false" />
</javaTypeResolver>

javaModelGenerator标签

该标签用来控制生成的实体类,根据 context 标签中配置的 defaultModelType 属性值的不同,一个表可能会对应生成多个不同的实体类。一个表对应多个类时使用并不方便,所以前面推荐使用 flat,保证一个表对应一个实体类。该标签必须配置一个,并且最多配置一个。

该标签只有两个必选属性。

  • targetPackage:生成实体类存放的包名。一般就是放在该包下,实际还会受到其他配置的影响。

  • targetProject:指定目标项目路径,可以使用相对路径或绝对路径。

该标签还支持以下几个 property 子标签属性。

  • constructorBased:该属性只对 MyBatis3 有效,如果为 true 就会使用构造方法入参,如果为 false 就会使用 setter 方式。默认为 false。

  • enableSubPackages:如果为 true,MBG 会根据 catalog 和 schema 来生成子包。如果为 false 就会直接使用 targetPackage 属性。默认为 false。

  • immutable:用来配置实体类属性是否可变。如果设置为 true,那么 constructorBased 不管设置成什么,都会使用构造方法入参,并且不会生成 setter 方法。如果为 false,实体类属性就可以改变。默认为 false。

  • rootClass:设置所有实体类的基类。如果设置,则需要使用类的全限定名称。并且,如果 MBG 能够加载 rootClass(可以通过 classPathEntry 引入 jar 包,或者 classpath 方式),那么 MBG 不会覆盖和父类中完全匹配的属性。匹配规则如下。

    • 属性名完全相同

    • 属性类型相同

    • 属性有 getter 方法

    • 属性有 setter 方法

  • trimStrings:判断是否对数据库查询结果进行 trim 操作,默认值为 false。如果设置为 true 就会生成如下代码。

public void setUsername(String username) {
    this.username = username == null ? null : username.trim();
}

javaModelGenerator 配置示例如下。

<javaModelGenerator targetPackage="test.model" targetProject="src\main\java">
    <property name="enableSubPackages" value="false" />
    <property name="trimStrings" value="false"/>
</javaModelGenerator>

sqlMapGenerator标签

该标签用于配置 SQL 映射生成器(Mapper.xml 文件)的属性,该标签可选,最多配置一个。如果 targetRuntime 设置为 MyBatis3,则只有当 javaClientGenerator 配置需要 XML 时,该标签才必须配置一个。如果没有配置 javaClientGenerator,则使用以下规则。

  • 如果指定了一个 sqlMapGenerator,那么 MBG 将只生成 XML 的 SQL 映射文件和实体类。

  • 如果没有指定 sqlMapGenerator,那么 MBG 将只生成实体类。

该标签只有两个必选属性。

  • targetPackage:生成 SQL 映射文件(XML 文件)存放的包名。一般就是放在该包下,实际还会受到其他配置的影响。

  • targetProject:指定目标项目路径,可以使用相对路径或绝对路径。

该标签还有一个可选的 property 子标签属性 enableSubPackages,如果为 true,MBG 会根据 catalog 和 schema 来生成子包。如果为 false 就会直接用 targetPackage 属性,默认为 false。

sqlMapGenerator 配置示例如下。

<sqlMapGenerator targetPackage="test.xml" targetProject="E:\MyProject\src\main\resources" >
    <property name="enableSubPackages" value="false" />
</sqlMapGenerator>

javaClientGenerator标签

该标签用于配置 Java 客户端生成器(Mapper 接口)的属性,该标签可选,最多配置一个。如果不配置该标签,就不会生成 Mapper 接口。

该标签有以下 3 个必选属性。

  • type:用于选择客户端代码(Mapper 接口)生成器,用户可以自定义实现,需要继承 org.mybatis.generator.codegen.AbstractJavaClientGenerator 类,必须有一个默认空的构造方法。该属性提供了以下预设的代码生成器,首先根据 context 的 targetRuntime 分成两类(不考虑 iBATIS)。

    • MyBatis3

      • ANNOTATEDMAPPER:基于注解的 Mapper 接口,不会有对应的 XML 映射文件。

      • MIXEDMAPPER:XML 和注解的混合形式,上面这种情况中的 SQL Provider 注解方法会被 XML 方式替代。

      • XMLMAPPER:所有的方法都在 XML 中,接口调用依赖 XML 文件。

    • MyBatis3Simple

      • ANNOTATEDMAPPER:基于注解的 Mapper 接口,不会有对应的 XML 映射文件。

      • XMLMAPPER:所有的方法都在 XML 中,接口调用依赖 XML 文件。

  • targetPackage:生成 Mapper 接口存放的包名。一般就是放在该包下,实际还会受到其他配置的影响。

  • targetProject:指定目标项目路径,可以使用相对路径或绝对路径。

该标签还有一个可选属性 implementationPackage,如果指定了该属性,Mapper 接口的实现类就会生成在这个属性指定的包中。

该标签还支持几个 property 子标签,由于这些属性不常用,因此不做介绍。

javaClientGenerator 标签中的 type 属性非常重要,此处提供一些选择的建议。

  • XMLMAPPER:推荐使用,将接口和 XML 完全分离,容易维护,接口中不出现 SQL 语句,只在 XML 中配置 SQL,修改 SQL 时不需要重新编译。

  • ANNOTATEDMAPPER:不推荐使用,纯注解方式的好处是,SQL 都在 Java 代码中,基本上只在一处写代码,看着方便。但是实际上维护不容易,写 SQL 过程中需要大量字符串拼接操作,复杂情况需要大量的 Java 判断,代码很乱,不容易维护。

  • MIXEDMAPPER:不推荐使用,这种情况下注解和 XML 混合使用会很乱,不利于维护。

javaClientGenerator 标签配置示例如下。

<javaClientGenerator type="XMLMAPPER" targetPackage="test.dao" targetProject="src\main\java" />

table标签

table 是最重要的一个标签,该标签用于配置需要通过内省数据库的表,只有在 table 中配置过的表,才能经过上述其他配置生成最终的代码,该标签至少要配置一个,可以配置多个。

table 标签有一个必选属性 tableName,该属性指定要生成的表名,可以使用 SQL 通配符匹配多个表。

例如要生成全部的表,可以如下配置。

<table tableName="%" />

table 标签包含多个可选属性。

  • schema:数据库的 schema,可以使用 SQL 通配符匹配。如果设置了该值,生成 SQL 的表名会变成如 schema.tableName 的形式。

  • catalog:数据库的 catalog,如果设置了该值,生成 SQL 的表名会变成如 catalog.tableName 的形式。

  • alias:如果指定,这个值会用在生成的 select 查询 SQL 表的别名和列名上,例如 alias_actualColumnName(别名_实际列名)。

  • domainObjectName:生成对象的基本名称。如果没有指定,MBG 会自动根据表名来生成名称。

  • enableXXX:XXX 代表多种 SQL 方法,该属性用来指定是否生成对应的 XXX 语句。

  • selectByPrimaryKeyQueryId:DBA 跟踪工具中会用到,具体请参考详细文档。

  • selectByExampleQueryId:DBA 跟踪工具中会用到,具体请参考详细文档。

  • modelType:和 context 的 defaultModelType 含义一样,这里可以针对表进行配置,配置会覆盖 context 的 defaultModelType 配置。

  • escapeWildcards:表示查询列是否对 schema 和表名中的 SQL 通配符(_ 和 %)进行转义。对于某些驱动,当 schema 或表名中包含 SQL 通配符时,转义是必须的。有一些驱动则需要将下画线进行转义,例如 MY_TABLE。默认值是 false。

  • delimitIdentifiers:是否给标识符增加分隔符。默认为 false。当 catalog、schema 或 tableName 中包含空白时,默认为 true。

  • delimitAllColumns:是否对所有列添加分隔符。默认为 false。

table 标签包含多个可用的 property 子标签,可选属性如下。

  • constructorBased:和 javaModelGenerator 中的属性含义一样。

  • ignoreQualifiersAtRuntime:生成的 SQL 中的表名将不会包含 schema 和 catalog 前缀。

  • immutable:和 javaModelGenerator 中的属性含义一样。

  • modelOnly:用于配置是否只生成实体类。如果设置为 true,就不会有 Mapper 接口,同时还会覆盖属性中的 enableXXX 方法,并且不会生成任何 CRUD 方法。如果配置了 sqlMapGenerator,并且 modelOnly 为 true,那么 XML 映射文件中只有实体对象的映射标签(resultMap)。

  • rootClass:和 javaModelGenerator 中的属性含义一样。

  • rootInterface:和 javaClientGenerator 中的属性含义一样。

  • runtimeCatalog:运行时的 catalog,当生成表和运行环境表的 catalog 不一样时,可以使用该属性进行配置。

  • runtimeSchema:运行时的 schema,当生成表和运行环境表的 schema 不一样时,可以使用该属性进行配置。

  • runtimeTableName:运行时的 tableName,当生成表和运行环境表的 tableName 不一样时,可以使用该属性进行配置。

  • selectAllOrderByClause:该属性值会追加到 selectAll 方法后的 SQL 中,直接与 order by 拼接后添加到 SQL 末尾。

  • useActualColumnNames:如果设置为 true,那么 MBG 会使用从数据库元数据获取的列名作为生成的实体对象的属性。如果为 false(默认值为 false),MGB 将会尝试将返回的名称转换为驼峰形式。在这两种情况下,可以通过 columnOverride 标签显式指定,此时将会忽略该属性。

  • useColumnIndexes:如果为 true,MBG 生成 resultMaps 时会使用列的索引,而不是结果中列名的顺序。

  • useCompoundPropertyNames:如果为 true,MBG 生成属性名的时候会将列名和列备注连接起来。这对于那些通过第四代语言自动生成列(例如 FLD22237)但是备注包中含有用信息(例如 “customer id”)的数据库来说很有用。在这种情况下,MBG 会生成属性名 FLD2237_CustomerId。

除了 property 子标签外,table 还包含以下子标签。

  • generatedKey(0 个或 1 个)

  • columnRenamingRule(0 个或 1 个)

  • columnOverride(0 个或多个)

  • ignoreColumn(0 个或多个)

下面对这 4 个子标签进行详细讲解。

generatedKey标签

该标签用来指定自动生成主键的属性(identity 字段或者 sequences 序列)。如果指定这个标签,MBG 将在生成 insert 的 SQL 映射文件中插入一个 selectKey 标签。这个标签非常重要,而且只能配置一个。

该标签包含以下两个必选属性。

  • column:生成列的列名。

  • sqlStatement:返回新值的 SQL 语句。如果这是一个 identity 列,则可以使用其中一个预定义的的特殊值,预定义值如下。

    • Cloudscape

    • DB2

    • DB2_MF

    • Derby

    • HSQLDB

    • Informix

    • MySQL

    • SQL Server

    • SYBASE

JDBC:使用该值时,MyBatis 会使用 JDBC 标准接口来获取值,这是一个独立于数据库获取标识列中的值的方法。

该标签还包含两个可选属性。

  • identity:当设置为 true 时,该列会被标记为 identity 列,并且 selectKey 标签会被插入在 insert 后面。当设置为 false 时,selectKey 会插入到 insert 之前(通常是序列)。切记:即使 type 属性指定为 post,仍然需要将 identity 列设置为 true,这会作为 MBG 从插入列表中删除该列的标识。该属性默认值是 false。

  • type:type=post 且 identity=true 时,生成的 selectKey 中 order=AFTER;当 type=pre 时,identity 只能为 false,生成的 selectKey 中 order=BEFORE。可以这么理解,自动增长的列只有插入到数据库后才能得到 ID,所以是 AFTER;使用序列时,只有先获取序列之后才能插入数据库,所以是 BEFORE。

table 配置示例一(针对 MySQL、SQL Server 等自增类型主键)。

<table tableName="user login info" domainObjectName="UserLoginInfo">
    <generatedKey column="id" sqlStatement="MySQL"/>
</table>

该配置生成的对应的 insert 方法如下。

<insert id="insert" parameterType="test.model.UserLoginInfo">
    <selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
        SELECT LAST_INSERT_ID()
    </selectKey>
    insert into `user login info` (Id, username, logindate, loginip)
    values (#{id,jdbcType=INTEGER}, #{username, jdbcType=VARCHAR},#{logindate,jdbcType=TIMESTAMP}, #{loginip, jdbcType=VARCHAR})
</insert>

table 配置示例二(针对 Oracle 序列)。

<table tableName="user login info" domainObjectName="UserLoginInfo">
    <generatedKey column="id" sqlStatement="select SEQ_ID.nextval from dual"/>
</table>

该配置生成的对应的 insert 方法如下。

<insert id="insert" parameterType="test.model.UserLoginInfo">
    <selectKey keyProperty="id" order="BEFORE" resultType="java.lang.Integer">
        select SEQ_ID.nextval from dual
    </selectKey>
    insert into `user login info` (Id, username, logindate, loginip)
    values (#{id,jdbcType=INTEGER}, #{username, jdbcType=VARCHAR},#{logindate,jdbcType=TIMESTAMP}, #{loginip, jdbcType=VARCHAR})
</insert>

columnRenamingRule标签

该标签最多可以配置一个,使用该标签可以在生成列之前对列进行重命名。这对于那些由于存在同一前缀的字段因此想在生成属性名时去除前缀的表非常有用。假设一个表包含以下列。

  • CUST_BUSINESS_NAME

  • CUST_STREET_ADDRESS

  • CUST_CITY

  • CUST_STATE

生成的所有属性名中如果都包含 CUST 的前缀可能会让人感觉不舒服。这些前缀可以通过如下方式定义重命名规则。

<columnRenamingRule searchString="^CUST_" replaceString=" " />

注意,MBG 内部使用 java.util.regex.Matcher.replaceAll 方法实现这个功能。请参阅有关该方法的文档和在 Java 中使用正则表达式的例子。

当 columnOverride 匹配一列时,columnRenamingRule 标签会被忽略。columnOverride 优先于重命名的规则。

该标签有一个必选属性 searchString,用于定义将要被替换的字符串的正则表达式。

该标签有一个可选属性 replaceString,用于替换搜索字符串列每一个匹配项的字符串。如果没有指定,就使用空字符串。

关于 table 的 property 属性 useActualColumnNames 对此标签的影响,可以查看完整文档。

columnOverride标签

该标签用于将某些默认计算的属性值更改为指定的值,标签可选,可以配置多个。

该标签有一个必选属性 column,表示要重写的列名。

该标签有多个可选属性,具体如下。

  • property:要使用的 Java 属性的名称。如果没有指定,MBG 会根据列名生成。例如,如果一个表的一列名为 STRT_DTE,MBG 会根据 table 的 useActualColumnNames 属性生成 STRT_DTE 或 strtDte。

  • javaType:列的属性值为完全限定的 Java 类型。如果需要,可以覆盖由 JavaTypeResolver 计算出的类型。

  • jdbcType:列的 JDBC 类型(如 INTEGER、DECIMAL、NUMERIC、VARCHAR 等)。如果需要,可以覆盖由 JavaTypeResolver 计算出的类型。

  • typeHandler:根据用户定义的需要用来处理列的类型处理器。必须是一个继承自 TypeHandler 接口的全限定的类名。如果没有指定或者是空白,MyBatis 会用默认的类型处理器来处理类型。切记:MBG 不会校验这个类型处理器是否存在或可用,MGB 只是简单地将值插入到已生成的 SQL 映射的配置文件中。

  • delimitedColumnName:指定是否应在生成的 SQL 的列名称上增加分隔符。如果列的名称中包含空格,MGB 会自动添加分隔符,所以只有当列名需要被强制为一个合适的名字或者列名是数据库中的保留字时,才是必要的。

columnOverride 配置示例如下。

<table schema="DB2ADMIN" tableName="ALLTYPES">
    <columnOverride column="LONG_VARCHAR_FIELD"
                    javaType="java.lang.String"
                    jabcType="VARCHAR" />
</table>

ignoreColumn标签

该标签可以用来屏蔽不需要生成的列,该标签可选,可以配置多个。

该标签有一个必选属性 column,表示要忽略的列名。

该标签还有一个可选属性 delimitedColumnName,标识匹配列名的时候是否区分大小写。如果为 true 则区分,默认值为 false,表示不区分大小写。