3. MyBatis Generator 插件

通用Mapper在1.0.0版本的时候增加了MyBatis Generator(以下简称MBG)插件,使用该插件可以很方便的生成实体类、Mapper接口以及对应的XML文件。

本篇文档就是讲述如何在MBG中使用该插件。

首先对MBG不太了解的可以先阅读下面的文档:

Mybatis Geneator 详解

http://git.oschina.net/free/Mybatis_Utils/tree/master/MybatisGeneator/MybatisGeneator.md

使用通用 Mapper 插件

插件代码在tk.mybatis.mapper.generator包下面,一共有如下两个类:

  • MapperCommentGenerator:该类用于生成数据库备注字段的注释,以及实体类字段的注解。
  • MapperPlugin:插件的实现类,该类默认使用上面这个注释生成器,插件屏蔽了一般的CRUD方法(保留了Example),插件可以生成实体的@Table注解。

另外本项目为了在Maven中配置更简单,从1.0.0版本开始上传Maven中央仓库。

<dependency>
    <groupId>tk.mybatis</groupId>
    <artifactId>mapper</artifactId>
    <!-- 建议使用最新版本 -->
    <version>x.x.x</version>
</dependency>

为什么用maven更方便,稍后会说明。

运行MBG有多种方法,这里只介绍两种比较常见的方法。并且有关的内容会针对这样的运行方式进行配置。

一、使用Java编码方式运行MBG

本项目测试代码中包含这个例子。

使用这种方式,首先下载MBG的Jar包(本项目测试代码中使用maven引入jar包,使用Java代码运行)。

MBG下载地址:http://repo1.maven.org/maven2/org/mybatis/generator/mybatis-generator-core/

Java代码很容易,和文档中的一样:

List<String> warnings = new ArrayList<String>();
boolean overwrite = true;
ConfigurationParser cp = new ConfigurationParser(warnings);
Configuration config = cp.parseConfiguration(
        Generator.class.getResourceAsStream("/generator/generatorConfig.xml"));
DefaultShellCallback callback = new DefaultShellCallback(overwrite);
MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings);
myBatisGenerator.generate(null);

你只需要在你当前的项目中创建一个类,添加一个main方法,在main中写上上面的代码即可。

这段代码容易,最主要的一个内容是"generatorConfig.xml",我们应该如何配置该类。

下面是一个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>
  <context id="Mysql" targetRuntime="MyBatis3Simple" defaultModelType="flat">

    <plugin type="tk.mybatis.mapper.generator.MapperPlugin">
      <property name="mappers" value="tk.mybatis.mapper.common.Mapper"/>
      <!-- caseSensitive默认false,当数据库表名区分大小写时,可以将该属性设置为true -->
      <property name="caseSensitive" value="true"/>
    </plugin>

    <jdbcConnection driverClass="com.mysql.jdbc.Driver"
                    connectionURL="jdbc:mysql://localhost:3306/test"
                    userId="root"
                    password="">
    </jdbcConnection>

    <javaModelGenerator targetPackage="test.model" targetProject="G:\MyProject\src\main\java"/>

    <sqlMapGenerator targetPackage="mapper"  targetProject="G:\MyProject\src\main\resources"/>

    <javaClientGenerator targetPackage="test.mapper" targetProject="G:\MyProject\src\main\java" type="XMLMAPPER" />

    <table tableName="%" >
      <generatedKey column="id" sqlStatement="Mysql" identity="true"/>
    </table>
  </context>
</generatorConfiguration>

下面逐段对上面的配置进行详解。

看下面这段,这段代码配置了通用Mapper的插件tk.mybatis.mapper.generator.MapperPlugin,该插件有一个必选的<property>属性mappers,这里的mappers和通用Mapper中的mappers配置含义一样,就是我们使用的通用Mapper接口,多个通用Mapper接口可以用逗号隔开。

<plugin type="tk.mybatis.mapper.generator.MapperPlugin">
    <property name="mappers" value="tk.mybatis.mapper.common.Mapper"/>
</plugin>

关于本插件,最重要的内容就是上面这个配置。下面要说的其他配置和普通的一致。

下面这段是数据库配置信息,由于需要连接数据库,需要保证项目的classpath下面有数据库的JDBC驱动。

<jdbcConnection driverClass="com.mysql.jdbc.Driver"
                    connectionURL="jdbc:mysql://localhost:3306/test"
                    userId="root"
                    password="">
</jdbcConnection>

下面这个配置是生成实体类的配置,是一个必须配置的内容。

<javaModelGenerator targetPackage="test.model" targetProject="G:\MyProject\src\main\java"/>

再下面的sqlMapGenerator是一个可选的配置,配置后可以生成Mapper接口对应的XML文件。

<sqlMapGenerator targetPackage="mapper"  targetProject="G:\MyProject\src\main\resources"/>

再往下就是通用Mapper接口的配置,配置javaClientGenerator后会生成对应的接口文件,该接口会自动继承前面配置的通用Mapper接口。

<javaClientGenerator targetPackage="test.mapper" targetProject="G:\MyProject\src\main\java" type="XMLMAPPER" />

最后一个配置table,这里使用SQL通配符%来匹配所有表。generatedKey意味着所有的表都有一个id自增的主键,在生成实体类的时候会根据该配置生成相应的注解。

<table tableName="%" >
    <generatedKey column="id" sqlStatement="Mysql" identity="true"/>
</table>

补充类似 Oracle 序列的配置方式

<generatedKey column="id" sqlStatement="select SEQ_{1}.nextval from dual" identity="false" type="pre"/>

这里的 {1} 代表的是对应表的大写形式,{0} 是小写形式。

这个配置生成的代码会像下面这样:

public class Author {
   @Id
   @GeneratedValue(strategy = GenerationType.IDENTITY,
           generator = "select SEQ_AUTHOR.nextval from dual")
   private Integer id;
   // 省略其他
}

这段配置介绍完了,之后运行前面的JAVA方法,就会生成对应的文件。该文件的样式最后贴个例子。

二、使用Maven执行MBG

这里有一个完整的例子,Mybatis-Spring,下面讲解的内容出自这个例子。

使用Maven插件的一个好处是可以将Maven中的属性使用${property}形式在generatorConfig.xml中引用。

先看Maven的pom.xml文件(只显示有关的部分内容):

<properties>
    <!--  MyBatis Generator  -->
    <!--  Java接口和实体类  -->
    <targetJavaProject>${basedir}/src/main/java</targetJavaProject>
    <targetMapperPackage>tk.mybatis.mapper.mapper</targetMapperPackage>
    <targetModelPackage>tk.mybatis.mapper.model</targetModelPackage>
    <!--  XML生成路径  -->
    <targetResourcesProject>${basedir}/src/main/resources</targetResourcesProject>
    <targetXMLPackage>mapper</targetXMLPackage>
    <!--  依赖版本  -->
    <mapper.version>1.0.0</mapper.version>
    <mysql.version>5.1.29</mysql.version>
</properties>

上面是pom.xml中properties配置的部分内容。这里配置了MBG配置文件中常用到的几个路径以及包名。还包含了通用Mapper的版本和数据库JDBC驱动的版本。

下面是MBG的Maven插件配置:

<plugin>
    <groupId>org.mybatis.generator</groupId>
    <artifactId>mybatis-generator-maven-plugin</artifactId>
    <version>1.3.2</version>
    <configuration>
        <configurationFile>${basedir}/src/main/resources/generator/generatorConfig.xml</configurationFile>
        <overwrite>true</overwrite>
        <verbose>true</verbose>
    </configuration>
    <dependencies>
        <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>${mysql.version}</version>
        </dependency>
        <dependency>
        <groupId>tk.mybatis</groupId>
        <artifactId>mapper</artifactId>
        <version>${mapper.version}</version>
        </dependency>
    </dependencies>
</plugin>

这里配置了MBG插件,并且配置了generatorConfig.xml配置文件的路径。另外还有两个依赖,分别是JDBC驱动以及通用Mapper(提供了MBG插件)。

下面我们在看看这个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="config.properties"/>

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

        <plugin type="${mapper.plugin}">
          <property name="mappers" value="${mapper.Mapper}"/>
        </plugin>

        <jdbcConnection driverClass="${jdbc.driverClass}"
                        connectionURL="${jdbc.url}"
                        userId="${jdbc.user}"
                        password="${jdbc.password}">
        </jdbcConnection>

        <javaModelGenerator targetPackage="${targetModelPackage}" targetProject="${targetJavaProject}"/>

        <sqlMapGenerator targetPackage="${targetXMLPackage}"  targetProject="${targetResourcesProject}"/>

        <javaClientGenerator targetPackage="${targetMapperPackage}" targetProject="${targetJavaProject}" type="XMLMAPPER" />

        <table tableName="%" >
          <generatedKey column="id" sqlStatement="Mysql" identity="true"/>
        </table>
    </context>
</generatorConfiguration>

可以看到这个配置文件中的大多数属性都使用${}形式替代了。使用<properties resource="config.properties"/>引入了config.properties属性配置,该文件内容如下:

# 数据库配置
jdbc.driverClass = com.mysql.jdbc.Driver
jdbc.url = jdbc:mysql://localhost:3306/test
jdbc.user = root
jdbc.password =

#c3p0
jdbc.maxPoolSize=50
jdbc.minPoolSize=10
jdbc.maxStatements=100
jdbc.testConnection=true

# 通用Mapper配置
mapper.plugin = tk.mybatis.mapper.generator.MapperPlugin
mapper.Mapper = tk.mybatis.mapper.common.Mapper

使用配置文件的目的是因为系统多处地方使用了这种配置,因而使用一个属性文件可以方便的保持一致。

除了引用配置文件中的属性外,部分还使用了pom.xml中的属性。这种方式使用起来更灵活。

运行

配置好之后如何运行呢?

在pom.xml这一级目录的命令行窗口执行mvn mybatis-generator:generate即可(前提是配置了mvn)。

生成的代码

下面是自动生成的代码的例子,这些例子可以在Mybatis-Spring这里找到。

一、实体类UserInfo

package tk.mybatis.mapper.model;

import javax.persistence.*;

@Table(name = "user_info")
public class UserInfo {
    @Id
    @Column(name = "Id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    /**
     * 用户名
     */
    private String username;

    /**
     * 密码
     */
    private String password;

    /**
     * @return Id
     */
    public Integer getId() {
        return id;
    }

    /**
     * @param id
     */
    public void setId(Integer id) {
        this.id = id;
    }

    /**
     * 获取用户名
     *
     * @return username - 用户名
     */
    public String getUsername() {
        return username;
    }

    /**
     * 设置用户名
     *
     * @param username 用户名
     */
    public void setUsername(String username) {
        this.username = username;
    }
}

代码过长,省略了一部分,完整查看:UserInfo

可以看到这里生成的注释是有意义的内容,注释来源于数据库表字段的注释。

这里还自动生成了几项注解的内容。

二、Mapper接口UserInfoMapper

package tk.mybatis.mapper.mapper;

import tk.mybatis.mapper.common.Mapper;
import tk.mybatis.mapper.model.UserInfo;

public interface UserInfoMapper extends Mapper<UserInfo> {
}

接口自动继承配置的通用Mapper接口,自动包含泛型实体。

三、Mapper.xml文件UserInfoMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="tk.mybatis.mapper.mapper.UserInfoMapper" >
    <resultMap id="BaseResultMap" type="tk.mybatis.mapper.model.UserInfo" >
        <!--
            WARNING - @mbggenerated
        -->
        <id column="Id" property="id" jdbcType="INTEGER" />
        <result column="username" property="username" jdbcType="VARCHAR" />
        <result column="password" property="password" jdbcType="VARCHAR" />
        <result column="usertype" property="usertype" jdbcType="VARCHAR" />
        <result column="enabled" property="enabled" jdbcType="INTEGER" />
        <result column="realname" property="realname" jdbcType="VARCHAR" />
        <result column="qq" property="qq" jdbcType="VARCHAR" />
        <result column="email" property="email" jdbcType="VARCHAR" />
        <result column="tel" property="tel" jdbcType="VARCHAR" />
    </resultMap>
</mapper>

xml文件只包含了实体的resultMap映射配置。