前提
最近在做创业项目的时候因为有比较多的新需求,需要频繁基于DDL生成Mybatis适合的实体、Mapper接口和映射文件。其中,代码生成器是MyBatis Generator(MBG),用到了Mybatis-Generator-Core相关依赖,这里通过一篇文章详细地分析这个代码生成器的使用方式。本文编写的时候使用的Mybatis-Generator版本为1.4.0,其他版本没有进行过调研。
引入插件
Mybatis-Generator的运行方式有很多种:
- 基于
mybatis-generator-core-x.x.x.jar和其XML配置文件,通过命令行运行。 - 通过
Ant的Task结合其XML配置文件运行。 - 通过
Maven插件运行。 - 通过
Java代码和其XML配置文件运行。 - 通过
Java代码和编程式配置运行。 - 通过
Eclipse Feature运行。
这里只介绍通过Maven插件运行和通过Java代码和其XML配置文件运行这两种方式,两种方式有个特点:都要提前编写好XML配置文件。个人感觉XML配置文件相对直观,后文会花大量篇幅去说明XML配置文件中的配置项及其作用。这里先注意一点:默认的配置文件为ClassPath:generatorConfig.xml。
通过编码和配置文件运行
通过编码方式去运行插件先需要引入mybatis-generator-core依赖,编写本文的时候最新的版本为:
<dependency>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-core</artifactId>
<version>1.4.0</version>
</dependency>
假设编写好的XML配置文件是ClassPath下的generator-configuration.xml,那么使用代码生成器的编码方式大致如下:
List<String> warnings = new ArrayList<>();
// 如果已经存在生成过的文件是否进行覆盖
boolean overwrite = true;
File configFile = new File("ClassPath路径/generator-configuration.xml");
ConfigurationParser cp = new ConfigurationParser(warnings);
Configuration config = cp.parseConfiguration(configFile);
DefaultShellCallback callback = new DefaultShellCallback(overwrite);
MyBatisGenerator generator = new MyBatisGenerator(config, callback, warnings);
generator.generate(null);
通过Maven插件运行
如果使用Maven插件,那么不需要引入mybatis-generator-core依赖,只需要引入一个Maven的插件mybatis-generator-maven-plugin:
<plugins>
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.4.0</version>
<executions>
<execution>
<id>Generate MyBatis Artifacts</id>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
<configuration>
<!-- 输出详细信息 -->
<verbose>true</verbose>
<!-- 覆盖生成文件 -->
<overwrite>true</overwrite>
<!-- 定义配置文件 -->
<configurationFile>${basedir}/src/main/resources/generator-configuration.xml</configurationFile>
</configuration>
</plugin>
</plugins>
mybatis-generator-maven-plugin的更详细配置和可选参数可以参考:Running With Maven。插件配置完毕之后,使用下面的命令即可运行:
mvn mybatis-generator:generate
XML配置文件详解
XML配置文件才是Mybatis-Generator的核心,它用于控制代码生成的所有行为。所有非标签独有的公共配置的Key可以在mybatis-generator-core的PropertyRegistry类中找到。下面是一个相对完整的配置文件的模板:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http:/.ARCHAR" property="orderId"/>
<result column="create_time" jdbcType="TIMESTAMP" property="createTime"/>
<result column="amount" jdbcType="DECIMAL" property="amount"/>
<result column="order_status" jdbcType="TINYINT" property="orderStatus"/>
</resultMap>
<delete id="deleteByPrimaryKey" parameterType="java.lang.Long">
delete
from t_order
where id = #{id,jdbcType=BIGINT}
</delete>
<insert id="insert" parameterType="club.throwable.entity.Order">
<selectKey keyProperty="id" order="BEFORE" resultType="java.lang.Long">
SELECT LAST_INSERT_ID()
</selectKey>
insert into t_order (id, order_id, create_time,
amount, order_status)
values (#{id,jdbcType=BIGINT}, #{orderId,jdbcType=VARCHAR}, #{createTime,jdbcType=TIMESTAMP},
#{amount,jdbcType=DECIMAL}, #{orderStatus,jdbcType=TINYINT})
</insert>
<update id="updateByPrimaryKey" parameterType="club.throwable.entity.Order">
update t_order
set order_id = #{orderId,jdbcType=VARCHAR},
create_time = #{createTime,jdbcType=TIMESTAMP},
amount = #{amount,jdbcType=DECIMAL},
order_status = #{orderStatus,jdbcType=TINYINT}
where id = #{id,jdbcType=BIGINT}
</update>
<select id="selectByPrimaryKey" parameterType="java.lang.Long" resultMap="BaseResultMap">
select id, order_id, create_time, amount, order_status
from t_order
where id = #{id,jdbcType=BIGINT}
</select>
<select id="selectAll" resultMap="BaseResultMap">
select id, order_id, create_time, amount, order_status
from t_order
</select>
</mapper>
编程式自定义类型映射#
笔者喜欢把所有的非长整型的数字,统一使用Integer接收,因此需要自定义类型映射。编写映射器如下:
public class DefaultJavaTypeResolver extends JavaTypeResolverDefaultImpl {
public DefaultJavaTypeResolver() {
super();
typeMap.put(Types.SMALLINT, new JdbcTypeInformation("SMALLINT",
new FullyQualifiedJavaType(Integer.class.getName())));
typeMap.put(Types.TINYINT, new JdbcTypeInformation("TINYINT",
new FullyQualifiedJavaType(Integer.class.getName())));
}
}
此时最好使用编程式运行代码生成器,修改XML配置文件:
<javaTypeResolver type="club.throwable.mbg.DefaultJavaTypeResolver">
<property name="forceBigDecimals" value="false"/>
</javaTypeResolver>
...
运行方法代码如下:
public class Main {
public static void main(String[] args) throws Exception {
List<String> warnings = new ArrayList<>();
// 如果已经存在生成过的文件是否进行覆盖
boolean overwrite = true;
ConfigurationParser cp = new ConfigurationParser(warnings);
Configuration config = cp.parseConfiguration(Main.class.getResourceAsStream("/generator-configuration.xml"));
DefaultShellCallback callback = new DefaultShellCallback(overwrite);
MyBatisGenerator generator = new MyBatisGenerator(config, callback, warnings);
generator.generate(null);
}
}
数据库的order_status是TINYINT类型,生成出来的文件中的orderStatus字段全部替换使用Integer类型定义。
小结
本文相对详尽地介绍了Mybatis Generator的使用方式,具体分析了XML配置文件中主要标签以及标签属性的功能。因为Mybatis在Java的ORM框架体系中还会有一段很长的时间处于主流地位,了解Mybatis Generator可以简化CRUD方法模板代码、实体以及Mapper接口代码生成,从而解放大量生产力。Mybatis Generator有不少第三方的扩展,例如tk.mapper或者mybatis-plus自身的扩展,可能附加的功能不一样,但是基本的使用是一致的。