欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

MyBatis-19MyBatis代码生成器-XML配置详解

程序员文章站 2022-04-22 08:24:01
...

概述

MyBatis-17MyBatis代码生成器(****)MBG使用

MyBatis-18MyBatis代码生成器-Example讲解

通过前两篇的实践后,我们来梳理下理论知识。

MBG拥有丰富的配置,以XML形式的标签和属性来实现。


XML文件头

首先按照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用于定义该配置文件中所有标签和属性的用法及限制。


根节点generatorConfiguration及三个子元素(properties、classPathEntry、context)

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

文件头以及根节点是MBG必备的基本信息,中间是MBG的自定义配置部分。

根元素为<generatorConfiguration>,包含子元素(按照严格的顺序):<properties>(0或一个),<classPathEntry>(0或多个),<context>(1或多个);


properties子元素 (0…1)

<properties>,指定外部的属性文件,然后在配置中就可以通过${property}来引用属性文件中的属性值了. 一般配置数据库连接较为常见。

属性可以通过resource或者url来指定,只能使用其中一个属性来执行,同时使用会报错。

  • resource:指定classpath下的属性文件, 类似com/artisan/db.properties这样的属性值

  • url:指定文件系统上的特定位置,一般通过file协议来加载指定路径位置的属性文件,如:<properties url="file:///xxx/jdbc.properties"/>


classPathEntry子元素 (0…N)

classPathEntry元素,可以配置多个,也可以不配。 一般来指定驱动路径.属性location,来指定jdbc驱动包的位置.如果将jar包放入了classpath中,就不用设置这个属性了.

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


context子元素 (1…N)

context元素:用于指定一组对象的环境.子元素用于指定连接到的数据库,要生成的对象的类型和要处理的数据库中的表.该元素只有一个必选属性id,来进行唯一标识.


深入了解context元素

context 可选属性

  • id 唯一标识

  • defaultModelType:设置MBG如何生成实体类.
  1. conditional 默认值,不会生成单独的Blob实体类,但是如果有联合主键,会生成一个主键实体类. 和hierarchical类似,如果一个表的主键只有一个字段,那么不回位该字段生成单独的实体类,而是会将该字段合并到基本实体类中。

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

  2. hierarchical,如果有联合主键,会生成单独的主键实体类,如果有Blob字段,会生成单独的Blob实体类,然后为所有的其他字段另外生成一个单独的实体类,MBG会在所有生成的实体类之间维护一个继承关系。


  • targetRuntime :这个属性用于指定生成代码的运行时目标
  1. MyBatis3 : 输出对象兼容MyBatis 3.0或更高版本,兼容JSE 5.0或更高版本的对象,包含泛型和注解.会生成 by example这类动态查询方法.
  2. MyBatis3Simple: 与上面的MyBatis3类似,但是不会生成by example`一类方法,只有少量的动态SQL

context 子元素

这些子标签有严格的配置顺序

1. property(0个或者多个)

2. plugin(0个或者多个)

3. commentGenerator(0个或者1个)

4. jdbcConnection(1个)

5. javaTypeResolver(0个或者1个)

6. javaModelGenerator(1个)

7. sqlMapGenerator(0个或者1个)

8. javaClientGenerator(0个或者1个)

9. table(1个或者多个)

property (0..N)

<property> (0..N) ,property以name,和value的形式来设置,支持的属性有

  • autoDelimitKeywords :自动识别数据库关键字,默认为false,设置为true后,如果遇到数据库关键字,用<columnOverride>替换.
  • beginnginDelimiter , endingDelimiter : 用作分隔符的符号,oracle中是”,而mysql中是`
  • javaFileEncoding : 设置Java文件的编码集,如果没有指定,则会使用系统默认编码.
  • javaFormatter :使用该属性来指定生成的java文件的用户指定的formater的完整的类名称,用于格式化java代码,这个类必须继承org.mybatis.generator.api.JavaFormatter,而且提供一个默认不含参数的构造方法.每个context持有一个单独的javaFormatter实例,默认的是org.mybatis.generator.api.dom.DefaultJavaFormatter
  • xmlFormatter : 格式化xml文件,与上述javaFormatter类似.

plugin (0..N)

用来定义一个插件,插件用于修改MBG生成的代码.类继承于 org.mybatis.generator.api.Plugin .

下面介绍缓存插件,全限定名为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">
</cache>

commentGenerator (0 or 1)

用于定义注释生成器的属性.注释生成器用来给由MBG生成的多种元素,Java自动,java方法,XML元素等等 生成注释. 默认的注释生成器将JavaDoc注释添加到所有生成的Java元素上,也会添加到每个生成的XML元素上.注释的目的是告诉用户这个元素是生成的,并且有可能重新生成,也就是说不应该修改这些地方.

可选属性 type,用来指定注释生成器类型.自定义的类要继承于 org.mybatis.generator.api.CommentGenerator.

使用子元素来设置属性:

  • suppressAllComments :用来指定MBG所生成的代码是否包含任何注释.默认为false,即都会生成注释.为true是,所有代码都不会生成注释,且代码不会并合并.
  • suppressDate : 用来指定生成的注释中是否包含生成的日期.默认为false. 设置为true,不会添加时间戳.
  • addRemarkComments: 注释是否添加数据库表的备注信息,默认false

jdbcConnection (1 Required)

设置数据库连接的属性.每个必须含有一个元素.

必选属性:
- driverClass : 访问数据库的JDBC驱动程序的完全名称.
- connectionURL : 用于访问数据的JDBC连接URL.

可选属性:

  • userId : 访问数据库的用户ID
  • password : 访问数据库的密码

可以设置子元素<property>指定的属性都会被添加到JDBC驱动程序的属性中.


javaTypeResolver (0 or 1)

java类型处理器,处理数据库中类型到Java中的类型.使用属性type来设置,默认使用JavaTypeResolverDefaultImpl来处理类型.

子元素property支持一个属性:
- forceBigDecimals : 是否强制将DECIMAL和NUMERIC的类型转换为BigDecimal类型,默认是false.

默认情况下的转换规则为:
1. 如果精度>0或者长度>18,使用BigDecimal.
2. 如果精度=0且10<=长度<=18,则使用Long
3. 如果精度=0且5<=长度<=9,则使用Integer
4. 如果精度=0且长度<5 ,则使用Short.


javaModelGenerator (1 Required)

该元素用于控制生成的实体类.有两个必选属性:

  • targetPackage : 生成实体类所在的包名.会为目标包名生成pacakge.
  • targetProject : 指定目标项目,运行于Eclipse或者IDEA等IDE时,这个属性是来指定项目的source root,一般就是 src/main/java这样的路径.不会为这个路径创建文件夹.

通过子元素来设置属性:

  • constructorBased : 是否为每个类生成一个使用所有字段的构造函数.只对MyBatis3有效,默认为false. 如果属性immutable被设置了,则这个属性会被忽略.可以在<table>中对具体的一个表进行设置.
  • enableSubPackages : 是否根据表的 catalog 和 schema 来生成一个子包,默认是false
  • immutable : 这个属性用于选择这些类是否是可变的,如果设置true,则这些类是不可变的,所有没有setter方法,且会忽略constructorBased属性,来默认提供一个含有所有参数的构造函数.默认是false.
  • rootClass : 这个属性用来指定所有生成的Java Model的基类,需要使用 fully qualified class name 如 com.xxx.xxx.RootClass. 如果生成对象生成的类型或者getter和setter方法在RootClass中存在,则不会自动生成和覆盖rootClass中的内容.
  • trimStrings : 这个属性用来设置对从数据库取回的字符串进行trim操作,默认为false.

sqlMapGenerator (0 or 1)

定义SQL映射生成器(Mapper.xml)的属性,SQL映射生成器会为每个表生成Mybatis使用的XML文件.如果没有指定这个元素,不会生成SQL映射的XML文件.如果使用MyBatis3,且设置了javaClientGenerator需要XML时,这个属性才是必选子元素.


可选属性:

  • targetPackage : 包所在位置
  • targetProject : 指定目标项目

可以通过子元素 来设置一个属性 :enableSubPackages:是否通过目录和schema来生成子包.


javaClientGenerator (0 or 1)

用于定义Java客户端代码生成器的属性.会生成Java的接口和类,可以简单的使用生成的Java Model和XML映射文件.在MyBatis中,会生成Mapper接口形式的代码.


必选属性:

  • type : 用户选择一个默认的生成器,或者使用用户自定义的DAO生成器.自定义需要继承与 org.mybatis.generator.codegen.AbstractJavaClientGenerator类.

    如果当前targetRuntime是 MyBatis3,有以下三个选项:

  1. ANNOTATEDMAPPER : 生成对象是 MyBatis3.x映射器基础结构的Java接口,这些接口会基于注解和SqlProviders,不会有XML文件生成.就是纯接口使用注解.会有Provider生成.
  2. MIXEDMAPPER :注解与XML混合,注解用在简单注解可以实现的地方,客户端不会生成SqlProvider,复杂的动态SQL都会生成在XML中.
  3. XMLMAPPER : 生成接口依赖XML文件.
如果targetRuntime是MyBatis3Simple没有MIXEDMAPPER选项.
  • targetPackage和targetProject

可选属性 :

  • implementationPackage : 如果指定了该属性,实现类就会生成在这个包中.

通过子元素 来设置属性:

  • enableSubPackages : 是否根据 catolog和scheme来生成不同的包.
  • exampleMethodVisibility :设置byExample方法是否可见,默认是public,可见,且在接口中声明方法.可以设置的属性有: public,private,protected,default,但是在MyBatis3中,忽略该属性.
  • methodNameCalculator : 属性用于为DAO方法提供不同的名称.被Mybatis3忽略.
  • rootInterface : 指定是否所有生成的接口都继承与一个父接口.使用 fully qualified class name.
  • useLegacyBuilder :默认是false.设置为true,会使用SqlBuilder为MyBatis生成动态SQL,在MyBatis3.2和以后被弃用.如果为false,则使用新的SQL生成器来生成客户端代码.

table (1..N)

从数据库中选择一个表,来生成对象.


必选属性:

  • tableName : 数据库表的名称,不包含 catalog和schema,可以指定SQL通配符,如”%”来匹配所有的表.名称的匹配的逻辑:如果名称中有空格,则以指定大小写来查找表,如果数据库标识为大写,则用大写,如果数据库标识为小写则用小写,否则,自行定义.在创建数据库时,如果使用”“来指定大小写了,即使数据库标识符是大写,也需要设置
    delimitIdentifiers = "true"来保留大小写格式.

可选属性:

  • schema : 可以指定通配符
  • catalog : 可以指定通配符
  • alias : 如果指定,则设置的别名会用在select查询上.
  • domainObjectName : 生成的对象的基本名称,如果没有指定,则会以表名来命名.由于带domain,所以可以生成到指定包中,如abc.Model,对象名是Model,添加到包abc中. enableInsert : 是否生成Insert语句,默认为true.
  • enableSelectByPrimaryKey :是否生成根据主键查询语句,默认为true.如果不存在主键,这不会生成根据主键查询的语句.
  • enableSelectByExample : 是否通过 Example进行动态查询.默认为true.
  • enableUpdateByPrimaryKey : 是否通过主键根据.默认为true
  • enableDeleteByPrimaryKey : 是否通过主键删除语句.默认为true.
  • enableUpdateByExample : 是否生成通过Example更新语句.默认为true.
  • enableDeleteByExample : 是否生成通过Example删除语句,默认为true.
  • enableCountByExample : 是否生成根据Example查询总数的语句,默认为true.
  • selectByPrimaryKeyQueryId : 这个值会以 <value> as QUERYID的形式被添加到主键查询语句的select列中.这样,可以对生成的每一个查询指定一个唯一的ID.
  • selectByExampleQueryId : 对每一次查询设置一个唯一id.
  • modelType : 可以用来重写默认的模型类型,即conditional,flat,和hierarchical三个属性.
  • escapeWildcards : 这个属性表示当查询列时,是否对schema和表名中的SQL通配符(如_和%)进行转义.默认是false.
  • delimitIdentifiers : 这个属性当查询表并且在生成的SQL中分割标识符时,是否使用指定的确切值.默认为false.如果catalog,schema或者tableName包含空白时,应该为true.
  • delimitAllColumns : 指示是否给生成SQL中所有的列名添加分割符.默认为false.

子元素有 :

  • <property> (0 .. N) : 通过property可以设置以下属性:

construtorBased : 是否产生一个含有所有字段的构造函数.默认为false
ignoreQualifiersAtRuntime: 生成的SQL的表名将不会包含schema和catalog的前缀.默认为false.
immutable :与<javaModelGenerator>中含义相同. modelOnly : 是否值生成模型类,而不生成CRUD方法.默认是false.
rootClass : 与<javaModelGenerator>中含义相同
rootInterface :与<javaModelGenerator>中含义相同.
runtimeCatalog :指定生成SQL语句中的catalog,生成代码的catalog会与运行时的catalog不同.
runtimeSchema : 运行时schema
runtimeTableName : 运行时表名.
selectAllOrderByClause :在MyBatis3SseColimple中,将这个属性以 oder by的形式添加到selectAll方法中.
useActualColumnNames : 默认为false.设置为true时,将从数据库元数据获取的列名作为实体类的属性名.false时,会将名称转换为驼峰形式.如果被<columnOverride>元素指定,则会忽略这个属性. 如START_DATE属性会变成 startDate属性.
useColumnIndexes :默认为false.且Mybatis3中不支持这个属性.如果为true,会在生成resultMaps时使用索引.
useCompoundPropertyNames : 默认为false. 如果为true,在生成属性名时,会将列名和备注连接起来.


  • <generatedKey> (0 or 1) :
    用于指定自动生成主键的属性.如果指定该元素,MBG会在生成insert的SQL映射文件中插入一个合适的<selectKey>元素.简单来说,就是可以用来做自增主键的设置.

必选属性:

  • column : 生成列 的列名.
  • sqlStatement : 返回新值的SQL语句.一些特殊值为 :MySql,转化为`SELECT LAST_INSERT_ID() . JDBC在MyBatis3中,生成正确的代码,且脱离数据库的限制.

可选属性:

  • identity : 默认为false.如果为true,被标记为identity列,且<selectKey>元素后被插入在insert后面.如果为false,则会被插入在insert之前.
  • type : 为selectKey元素指定类型, pre或post.指定类型后,selectKey永远在insert语句之前.

理解这个序列的意思,和插入前后的意思.序列表示表是一个序列,插入之前要先查询表,就需要知道当前指向的位置即主键.而自增主键要在插入之后,才能知道自己的大小.


  • <columnRenamingRule> (0 or 1)

    列的重命名规则.MBG使用正则表达式来进行重命名规则的实现,如果有<columnOverride>,则忽略<columnRenamingRule>属性.先使用这个重命名规则后,获得的结果再去使用useActualColumnNames规则来判断是非需要再次更新属性名.


必选属性:

  • searchString : 定义将被替换的子字符串的正则表达式.

可选属性:

  • replaceString : 替换匹配的字符串.如果没有设置,则用空字符串替换.

  • <columnOverride> (0 … N)

将默认得到的列进行修改,来设置指定的类型,名称等.

必选属性:

  • column : 列名

可选属性:

  • property : 要使用的Java名称.
  • javaType : 完全指定的Java类型.这里有必要来处理奇怪的数据库类型,如mysql中的unsigned
    bigint需要被映射为java.lang.Object.
  • jdbcType : 该列的JDBC类型(INTEGER,DECIMAL等等)
  • typeHandler : 用户定义的需要用来处理该列的类型处理器.
  • delimitedColumnName : 是否需要分割列名,指的是列名可能是带空格或者保留字,所以是否需要添加分隔符.默认为false.

  • <ignoreColumn> (0 … N)

忽略的列.

可选属性:

  • delimitedColunmnName : 当匹配对从数据库返回列时,是否区分大小写.默认为false.

使用心得

  • 可以考虑实体类类型defaultModelType为 flat,即只有一个对象,这样管理起来更加方便.
  • 注释的时间戳suppressDate一般都会关闭,因为每次重新生成都会修改时间戳,SVN都要重新提交,不利于多人开发.
  • 将jdbc驱动放在项目的classPath下,而不是使用<classPathEntry>来引入jar包.
  • 对于字符串类型,一般都设置trimStrings来去除空格.
  • <table>中配置<generatedKey>,来实现自增主键.
  • 在Mysql中,支持无符号数,但是java中的数据类型都是有符号的,所以要用<columnOverride>来解决这个问题,先将类型转换成java.lang.Object,然后在使用时,将返回值强制转换为适当的类型.

demo

在JDBC配置文件db.properties中,对项目文件夹布局进行指定:

# 包路径
model.package=com.artisan.mybatis.pojo
dao.package=com.artisan.mybatis.dao
xml.mapper.package=com.artisan.mybatis.mapping
target.project=src/main/java

编写配置文件generatorConfig.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">

<generatorConfiguration>
    <!-- 引用外部配置文件 -->
     <properties resource="db.properties" />

    <context id="MySqlContext" targetRuntime="MyBatis3" defaultModelType="flat">
        <!--关闭时间注释 -->
        <commentGenerator>
            <property name="suppressDate" value="true"/>
        </commentGenerator>

        <!--数据库连接信息 -->
        <jdbcConnection 
             driverClass="${jdbc.driver}"
             connectionURL="${jdbc.url}"
             userId="${jdbc.username}"
             password="${jdbc.password}">
        </jdbcConnection>

        <!--生成的model 包路径 -->
        <javaModelGenerator targetPackage="${model.package}" targetProject="${target.project}">
            <property name="enableSubPackages" value="ture"/>
            <property name="trimStrings" value="true"/>
        </javaModelGenerator>

        <!--生成xml mapper文件 路径 -->
        <sqlMapGenerator targetPackage="${xml.mapper.package}" targetProject="${target.project}">
            <property name="enableSubPackages" value="ture"/>
        </sqlMapGenerator>

        <!-- 生成的Dao接口 的包路径 -->
        <javaClientGenerator type="XMLMAPPER" targetPackage="${dao.package}" targetProject="${target.project}">
            <property name="enableSubPackages" value="ture"/>
        </javaClientGenerator>

        <!--对应数据库表名 -->
        <table tableName="%">
            <generatedKey column="id" sqlStatement="Mysql"/>
        </table>


    </context>
</generatorConfiguration>