一、官方相关文档
- github:
https://github.com/mybatis/generator
- 文档:
http://mybatis.org/generator/index.html
二、常用标签详解
上一篇博客 1.MyBatis generator - 简单使用(1) 大概过了一遍生成需要配置的基本属性,这篇主要具体介绍下常用的4类标签的属性配置:
- javaModelGenerator标签:实体类包名、存放目录配置
- javaClientGenerator标签:Dao包名、存放目录配置
- sqlMapGenerator标签:xml包名、存放目录、生成方式配置
- table标签:表的配置,进一步配置实体类、Dao、xml文件
2.1 javaModelGenerator标签
用于设置生成java实体类的包名和实体类存放的目录。
实体类名等配置参考2.4<table>
标签配置
(1)标签的属性:
属性 | 必填 | 描述 |
---|---|---|
targetPackage | 是 | 简单可以理解为实体类的包名 |
targetProject | 是 | 实体类存放目录,目录不存在,则会创建目录。可以是相对路径:在本项目中生成;也可以是具体某个项目的绝对路径 |
(2)子标签:仅支持<property>
(3)property支持的配置:
属性名 | 默认值 | 描述 |
---|---|---|
constructorBased | false | 是否为实体类生成构造方法;immutable=true,则本属性会被设置为true;本属性可以被<table> 标签相关的属性覆盖 |
enableSubPackages | false | 是否根据表的catalog和schema生成不同的包。例如order表的schema是my_schema,targetPackage=com.momo.test,本属性为true时,实体类的包:com.momo.test.my_schema |
exampleTargetPackage | Example类的包名,默认是实体类所在的包 | |
exampleTargetProject | Example类存放的目录,默认是实体类所在的目录 | |
immutable | false | 是否生成不可变的实体类,也就是只有构造方法,没有setter |
rootClass | 所有实体类的父类,如果父类定义了一些字段以及对应的getter、setter方法,那么实体类中就不会再生成。必须要类的安全限定名,如com.momo.test.BasePo | |
trimStrings | false | 是否去除空白字符,假如数据库中有char类型的字段会有用。可以被<table> 或<columnOverride> 标签的 trimStrings 覆盖 |
示例:
<context id="context1" targetRuntime="MyBatis3" >
<!-- 实体类配置 -->
<javaModelGenerator targetPackage="com.momo.test.order.po" targetProject="src/main/java">
<property name="trimStrings" value="true"/>
</javaModelGenerator>
</context>
2.2 javaClientGenerator标签
生成Dao接口(Mapper)
(1)标签的属性:
属性 | 必填 | 描述 |
---|---|---|
type | 是 | dao代码生成风格,或指定自定义的生成器。可选值:ANNOTATEDMAPPER、MIXEDMAPPER、XMLMAPPER |
targetPackage | 是 | Dao的包名 |
targetProject | 是 | Dao存放目录,目录不存在,则会创建目录。可以是相对路径:在本项目中生成;也可以是具体某个项目的绝对路径 |
type属性:
- 可选值:
- ANNOTATEDMAPPER:注解风格的Mapper,会生成
xxxMapper.java
和xxxSqlProvider.java
,不生成xxxMapper.xml
,此时就算配置了<sqlMapGenerator>
标签也不起作用了(参考2.3) - MIXEDMAPPER:混合式的Mapper,会生成注解风格的
xxxMapper.java
和xxxMapper.xml
- XMLMAPPER:XML的Mapper,会生成纯接口风格的
xxxMapper.java
和xxxMapper.xml
- ANNOTATEDMAPPER:注解风格的Mapper,会生成
- 自定义代码生成器
- 自定义的生成器必须继承
org.mybatis.generator.codegen.AbstractJavaClientGenerator
,且有public默认的构造方法
- 自定义的生成器必须继承
- 注:
- 若
<context>
标签的targetRuntime
属性是MyBatis3Simple
,那么可选值:ANNOTATEDMAPPER、XMLMAPPER
- 若
(2)子标签:仅支持<property>
(3)property支持的配置:
属性名 | 默认值 | 描述 |
---|---|---|
enableSubPackages | false | 是否根据表的catalog和schema生成不同的包。例如order表的schema是my_schema,targetPackage=com.momo.test,本属性为true时,实体类的包:com.momo.test.my_schema |
rootInterface | false | 所有Dao的父类,如果父类定义了一些方法,那么Dao中就不会再生成。必须要类的安全限定名,如com.momo.test.BaseDao |
useLegacyBuilder | false | true,注解的方法会使用MyBatis的SqlBuilder生成动态SQL;在MyBatis3.2及后续版本中,这种builder废弃了 |
示例:
<context id="context1" targetRuntime="MyBatis3" >
<!-- DAO,type:ANNOTATEDMAPPER、MIXEDMAPPER、XMLMAPPER -->
<javaClientGenerator type="XMLMAPPER" targetPackage="com.momo.test.order.mapper" targetProject="src/main/java">
<property name="enableSubPackages" value="true" />
</javaClientGenerator>
</context>
2.3 sqlMapGenerator标签
用于定义SQL映射生成器的属性,该生成器为每张表构造一个MyBatis风格的SQL映射xml(xxxMapper.xml)。
注:
- 若
<javaClientGenerator>
的type属性为ANNOTATEDMAPPER
,那么该标签会被忽略 - 若没有
<javaClientGenerator>
标签:- 但是有
<sqlMapGenerator>
标签:只会生成实体类和xml文件 - 也没有
<sqlMapGenerator>
标签:只会生成实体类
- 但是有
(1)标签的属性:
属性 | 必填 | 描述 |
---|---|---|
type | 是 | dao代码生成风格,或指定自定义的生成器。可选值:ANNOTATEDMAPPER、MIXEDMAPPER、XMLMAPPER |
targetPackage | 是 | xml文件的包名 |
targetProject | 是 | xml文件存放目录,目录不存在,则会创建目录。可以是相对路径:在本项目中生成;也可以是具体某个项目的绝对路径 |
(2)子标签:仅支持<property>
(3)property支持的配置:
属性名 | 默认值 | 描述 |
---|---|---|
enableSubPackages | false | 是否根据表的catalog和schema生成不同的包。例如order表的schema是my_schema,targetPackage=com.momo.test,本属性为true时,实体类的包:com.momo.test.my_schema |
示例:
<context id="context1" targetRuntime="MyBatis3" >
<!-- xxxMapper.xml -->
<sqlMapGenerator targetPackage="com.momo.test.mapper" targetProject="src/main/java">
<property name="enableSubPackages" value="true" />
</sqlMapGenerator>
</context>
2.4 table标签
指定数据库中表,生成对应的实体类。
(1)标签的属性:
属性 | 必填 | 默认值 | 描述 |
---|---|---|---|
tableName | 是 | 表名,不包括schema或catalog | |
schema | 否 | 数据库的schema,若数据库没有使用schema或使用的是默认schema,不需要配置 | |
catalog | 否 | 数据库的catalog,若数据库没有使用catalog或使用的是默认catalog,不需要配置 | |
alias | 否 | 别名,若配置别名t,则列名=t_列名 ,表名:select * from user t ,对实体类无影响 | |
domainObjectName | 否 | 类名,若不指定则根据表名生成,包括实体类、Dao、xml文件名称 | |
mapperName | 否 | Dao、xml文件名称,默认是domainObjectName+Mapper ,若指定该属性,则使用配置的值作为Dao、xml。该属性可以是 xxxMapper,也可以是 foo.xxxMapper,foo包会被添加到<sqlMapGenerator> 标签targetPackage属性后面 | |
sqlProviderName | 否 | true | SqlProvider类名,默认是domainObjectName+SqlProvider ,该属性只有在<javaClientGenerator> 标签的type=ANNOTATEDMAPPER 才会起作用 |
enableInsert | 否 | true | 是否生成insert语句 |
enableSelectByPrimaryKey | 否 | true | 是否生成根据主键查询,若表没有主键,则不生成 |
enableSelectByExample | 否 | true | 是否生成根据Example查询,开启后就会生成 xxxExample类,Mapper和xml会生成对应的方法 |
enableUpdateByPrimaryKey | 否 | true | 是否生成根据主键更新,若表没有主键,则不生成 |
enableDeleteByPrimaryKey | 否 | true | 是否生成根据主键删除,若表没有主键,则不生成 |
enableCountByExample | 否 | true | 是否生成根据Example统计 |
enableUpdateByExample | 否 | true | 是否生成根据Example更新 |
selectByPrimaryKeyQueryId | 否 | 若配置了值,如:id001, 那么根据主键查询语句里新增 'id001' as QUERYID ,DBA定位查询时比较好使 | |
selectByExampleQueryId | 否 | 若配置了值,如:id001, 那么根据Example查询语句里新增 'id001' as QUERYID ,DBA定位查询时比较好使 | |
modelType | 否 | 生成实体类方式,若不指定,使用默认的生成方式;可选值:conditional 、flat 、hierarchical ;hierarchical:这种方式会生成三个实体类,主键、BLOB列、普通列;flat:只生成一个实体类;conditional:和hierarchical类似,假如实体类只有一个字段,就不会生成,会被合并到主的实体类中,例如只有一个主键,那么就不会为主键单独生成一个类 | |
escapeWildcards | 否 | false | 在搜索列时是否转义schema和表中的SQL通配符(“ _”和“%”) |
delimitIdentifiers | 否 | false | 搜索表时是否区分大小写,然后生成的SQL中添加标识符。例如配置的标识符是``,那么在出现表名的地方就会添加这个标识符,select * from `user`,分隔符可以在<context> 标签下通过beginningDelimiter 、endingDelimiter 配置 |
delimitAllColumns | 否 | false | 是否对表的所有列添加分隔符,分隔符的配置同上;可以通过<columnOverride> 为每个属性配置是否需要分隔 |
(2)子标签
<property>
:属性<generatedKey>
:生成获取自增长id的语句<domainObjectRenamingRule>
:实体类命名规则<columnRenamingRule>
:列命名规则<columnOverride>
:列配置,会覆盖table标签上的配置<ignoreColumn>
:忽略的列
(3)property标签支持的配置:
属性名 | 默认值 | 描述 |
---|---|---|
constructorBased | false | 为实体类生成一个构造方法,没有setter方法。若immutable =true,则该属性强制为true |
ignoreQualifiersAtRuntime | false | 是否在生成SQL时在表前添加schema或catalog |
immutable | false | 是否生成不可变的实体类,也就是只有构造方法,没有setter |
modelOnly | false | 是否仅生成实体类,此时不生成xxxMapper.java,若配置了<sqlMapGenerator> ,会生成xxxMapper.xml,但只生成<resultMap> 元素 |
rootClass | 所有实体类的父类,如果父类定义了一些字段以及对应的getter、setter方法,那么实体类中就不会再生成。必须要类的安全限定名,如`com.momo.test.BasePo | |
rootInterface | 所有Dao的父类,如果父类定义了一些方法,那么Dao中就不会再生成。必须要类的安全限定名,如com.momo.test.BaseDao | |
runtimeCatalog | 若配置了该属性,则在生成SQL使用配置的值作为catalog | |
runtimeSchema | 若配置了该属性,则在生成SQL使用配置的值作为catalog | |
runtimeTableName | 若配置了该属性,则在生成SQL使用配置的值作为表名,上面配置的表名用于连接数据读取字段使用 | |
selectAllOrderByClause | selectAll方法生成order by xxx,例如配置c_time desc ,就会生成 order by c_time desc 。此配置仅在<context> 标签的targetRuntime配置为MyBatis3Simple才起作用 | |
trimStrings | false | 是否去除空白字符,假如数据库中有char类型的字段会有用。可以覆盖<javaModelGenerator> 标签的配置,被<columnOverride> 标签的 trimStrings 覆盖 |
useActualColumnNames | false | 是否使用实际的数据库列名生成实体类,例如START_DATE,那么实体类就是START_DATE,getter、setter方法就是getSTART_DATE()、setSTART_DATE()。默认false,则为startDate,getStartDate()、setStartDate() |
useColumnIndexes | false | 在结果映射,使用列的索引而不是列名作为,此配置在<context> 标签的targetRuntime配置为MyBatis3不起作用 |
useCompoundPropertyNames | false | 是否通过 列名+列注释 作为实体类的字段,例如:列名是 FLD2237,注释是:customer id,那么实体类的字段则为 FLD2237_CustomerId 。这可能在第4代语言创建的数据库中有点用处 |
示例:
<context id="context1" targetRuntime="MyBatis3" >
<property name="autoDelimitKeywords" value="true"/>
<property name="beginningDelimiter" value="`"/>
<property name="endingDelimiter" value="`"/>
<table tableName="product_item" domainObjectName="ProductItem"
delimitIdentifiers="true" delimitAllColumns="true"
enableCountByExample="false" enableDeleteByExample="false"
enableSelectByExample="false" enableUpdateByExample="false">
<property name="trimStrings" value="true"/>
<!-- 获取自增主键 -->
<generatedKey column="id" sqlStatement="MySql"/>
</table>
</context>
三、其他标签
3.1 context标签
生成一系列实体、Dao、XML的环境(上下文)。子标签用于指定数据库连接、实体类和Dao的类型、要插入的表。
可以配置多个<context>
标签,用于从不同数据库生成对象,或配置不同的生成参数。
(1)标签的属性:
属性 | 必填 | 默认值 | 描述 |
---|---|---|---|
id | 是 | 上下文的唯一标识。一些错误信息会和该id关联 | |
defaultModelType | 否 | conditional | 默认的实体类生成方式,可选值:conditional、flat、hierarchical,含义参考2.3<table> 标签的modelType属性 |
targetRuntime | 否 | MyBatis3DynamicSql | 生成代码的运行时目标,可选值:MyBatis3DynamicSql、MyBatis3Kotlin、MyBatis3、MyBatis3Simple、MyBatis3DynamicSqlV1 |
introspectedColumnImpl | 否 | 自定义列的信息,填写类的完全类限定名,该类需要继承org.mybatis.generator.api.IntrospectedColumn |
targetRuntime属性:
- MyBatis3DynamicSql:默认,生成的对象适配MyBatis3.4.2及以上、Java8及以上版本(用到了java8一些特性),有以下注意点:
- 实体类以
FLAT
方式生成,忽略defaultModelType
设置的值;同时不会生成with BLOBs
和"without BLOBs
方法 - Dao以注解方式生成,忽略
<javaClientGenerator>
标签的type属性设置的值 - 不会生成XML文件,所以
<sqlMapGenerator>
标签无需配置 <table>
标签的alias设置的值会被忽略,因为
- 实体类以
- MyBatis3Kotlin:Kotlin语言,生成的对象适配MyBatis3.0及以上、Java5及以上版本
- MyBatis3:生成的对象适配MyBatis3.4.2及以上版本
- 默认会生成Example方法,用于支持动态查询
- 生成的代码用到了Java5的许多特性,如参数化类型、注解
- MyBatis3Simple:生成的对象适配MyBatis3.4.2及以上版本
- 和MyBatis3类似,不过只会生成CRUD方法
- 不生成Example
- MyBatis3DynamicSqlV1:已废弃,后续版本可能会被移除
(2)子标签:
<property>
:属性,0或多<plugin>
:插件,0或多<commentGenerator>
:注释生成器,最多1个<connectionFactory>
:和jdbcConnection二选一<jdbcConnection>
:和connectionFactory二选一<javaTypeResolver>
:java类型解析器,最多1个<javaModelGenerator>
:实体类配置,必须且只能配置1个<sqlMapGenerator>
:XML配置,最多1个<javaClientGenerator>
:Dao配置,最多1个<table>
:表配置,至少1个
(3)property支持的配置:
属性名 | 默认值 | 描述 |
---|---|---|
autoDelimitKeywords | false | 数据库关键词分隔符,默认""分隔,例如type、name、status都属于MySQL的关键词。查看MyBatis支持的关键词org.mybatis.generator.internal.db.SqlReservedWords |
beginningDelimiter | " | 开始的分隔符,可以分隔关键词、表名、所有列,可以在<table> 标签中配置列是否需要分隔符 |
endingDelimiter | " | 结束的分隔符,可以分隔关键词、表名、所有列 |
javaFileEncoding | false | 生成的Java文件编码,若已存在的文件,在合并时将会使用该编码进行读取和写入 |
javaFormatter | false | 自定义Java格式化器,默认的格式化器org.mybatis.generator.api.dom.DefaultJavaFormatter ,自定义的格式化器需要实现org.mybatis.generator.api.JavaFormatter ,以及有个无参的默认构造方法 |
targetJava8 | true | 生成的代码使用Java8+特性 |
kotlinFileEncoding | false | kotlin文件编码 |
kotlinFormatter | false | kotlin代码格式化器 |
xmlFormatter | false | XML文件格式化器,默认org.mybatis.generator.api.dom.DefaultXmlFormatter ,自定义的格式化器需要实现org.mybatis.generator.api.XmlFormatter ,以及有个无参的默认构造方法 |
示例:
<generatorConfiguration>
<!-- 上下文,可配置多个,id唯一 -->
<context id="context1" targetRuntime="MyBatis3">
<!-- 分隔数据库关键词 -->
<property name="autoDelimitKeywords" value="true"/>
<!-- 分隔符 -->
<property name="beginningDelimiter" value="`"/>
<property name="endingDelimiter" value="`"/>
<!-- 插件 -->
<!--<plugin type="org.mybatis.org.mybatis.generator.plugins.MySqlPaginationPlugin"/>-->
<!-- 不生成注释 -->
<commentGenerator>
<property name="suppressAllComments" value="true"/>
</commentGenerator>
<!-- 修改mysql 数据源 -->
<jdbcConnection driverClass="com.mysql.jdbc.Driver" connectionURL="jdbc:mysql://127.0.0.1:3306/test"
userId="root" password="root"/>
</context>
</generatorConfiguration>
附上一份比较常用的配置:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"src/main/org/mybatis/generator/config/xml/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
<!-- 上下文,可配置多个,id唯一 -->
<context id="context1" targetRuntime="MyBatis3">
<!-- 分隔符 -->
<property name="beginningDelimiter" value="`"/>
<property name="endingDelimiter" value="`"/>
<!-- 不生成注释 -->
<commentGenerator>
<property name="suppressAllComments" value="true"/>
</commentGenerator>
<!-- 2.修改mysql 数据源 -->
<jdbcConnection driverClass="com.mysql.jdbc.Driver" connectionURL="jdbc:mysql://127.0.0.1:3306/test"
userId="root" password="root"/>
<!-- 3.修改Bean、Dao、xml存放目录 -->
<!-- 生成实体类类 -->
<javaModelGenerator targetPackage="com.momo.test.biz.trade.po" targetProject="src/main/java">
<property name="enableSubPackages" value="true" />
<property name="trimStrings" value="true" />
</javaModelGenerator>
<!-- 生成 xxxMapper.xml -->
<sqlMapGenerator targetPackage="com.momo.test.mapper" targetProject="src/main/java">
</sqlMapGenerator>
<!-- 生成Dao,xxxMapper.java -->
<javaClientGenerator type="XMLMAPPER" targetPackage="com.momo.test.biz.order.mapper" targetProject="src/main/java">
</javaClientGenerator>
<!-- 表配置,指定表名、列分隔,不生成Example,获取自增长id -->
<table tableName="product_item" domainObjectName="ProductItem"
delimitIdentifiers="true" delimitAllColumns="true"
enableCountByExample="false" enableDeleteByExample="false"
enableSelectByExample="false" enableUpdateByExample="false">
<property name="trimStrings" value="true"/>
<!-- 获取自增主键 -->
<generatedKey column="id" sqlStatement="MySql"/>
</table>
</context>
</generatorConfiguration>