使用MyBatis Generator逆向生成数据库读写代码

简介

MyBatis(前身是iBATIS)是一个基于Java的持久层框架,而MyBatis Generator (MBG)是一个根据数据库表结构为MyBatis和iBATIS逆向生成相关Java代码和配置文件的工具。
MBG可以生成:

  1. Java POJO,与数据库表结构对应;
  2. MyBatis和iBATIS规范的SQL映射配置文件,每个配置文件包含对一个表实现简单CRUD操作的SQL语句;
  3. MyBatis和iBATIS规范的Java客户端接口,提供对数据的增、删、查、改方法。

示例数据库

数据库表模型
示例数据库包含3张表:

  1. 课程表(course),存储课程名称、学分信息,主键为自增整数;
  2. 学生表(student),存储学生姓名、性别、年龄等信息,主键为自增整数;
  3. 得分表(score),存储某位学生某门课程的分数,使用课程id和学生id作为联合主键。

使用MBG逆向生成代码

使用MBG生成代码时,需要指定配置文件(generatorConfig.xml),如下所示,其中指定了数据库连接方式,Java POJO、SQL映射配置文件、Java客户端接口的生成方式和生成路径等:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<?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>
<classPathEntry location="/Users/tao/develop/mysql-connector-java-5.1.12.jar" />
<context id="test" targetRuntime="MyBatis3">
<commentGenerator>
<property name="suppressAllComments" value="true" />
</commentGenerator>
<jdbcConnection driverClass="com.mysql.jdbc.Driver" connectionURL="jdbc:mysql://xxx.xxx.xxx.xxx:3306/test" userId="xxx" password="xxx">
</jdbcConnection>
<javaTypeResolver>
<property name="forceBigDecimals" value="false" />
</javaTypeResolver>
<javaModelGenerator targetPackage="com.magicwt.bean" targetProject="/Users/tao/develop/test/src">
<property name="enableSubPackages" value="false" />
<property name="trimStrings" value="true" />
</javaModelGenerator>
<sqlMapGenerator targetPackage="com.magicwt.mapper" targetProject="/Users/tao/develop/test/src">
<property name="enableSubPackages" value="false" />
</sqlMapGenerator>
<javaClientGenerator type="XMLMAPPER" targetPackage="com.magicwt.dao" targetProject="/Users/tao/develop/test/src">
<property name="enableSubPackages" value="false" />
</javaClientGenerator>
<table tableName="%" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"></table>
</context>
</generatorConfiguration>

指定配置文件后,MBG支持以下4种生成代码方式:

  1. 使用命令行生成代码;
  2. 作为Ant任务生成代码;
  3. 作为Maven插件生成代码;
  4. 使用Java接口编程生成代码。

这里使用命令行方式,从https://github.com/mybatis/generator/releases 下载jar包,命令行下执行jar包:

java -jar mybatis-generator-core-1.3.2.jar -configfile generatorConfig.xml

执行成功后,便会生成如下代码:

  1. Java POJO:Course.java,Student.java,ScoreKey.java,Score.java,其中Course.java对应于course表,如下所示:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    package com.magicwt.bean;

    public class Course {
    private Integer id;

    private String name;

    private Byte credit;

    public Integer getId() {
    return id;
    }

    public void setId(Integer id) {
    this.id = id;
    }

    public String getName() {
    return name;
    }

    public void setName(String name) {
    this.name = name == null ? null : name.trim();
    }

    public Byte getCredit() {
    return credit;
    }

    public void setCredit(Byte credit) {
    this.credit = credit;
    }
    }
  2. SQL映射配置文件:CourseMapper.xml,StudentMapper.xml,ScoreMapper.xml,其中CourseMapper.xml包含对course表实现CRUD操作的SQL语句,如下所示:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    <?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="com.magicwt.dao.CourseMapper" >
    <resultMap id="BaseResultMap" type="com.magicwt.bean.Course" >
    <id column="id" property="id" jdbcType="INTEGER" />
    <result column="name" property="name" jdbcType="VARCHAR" />
    <result column="credit" property="credit" jdbcType="TINYINT" />
    </resultMap>
    <sql id="Base_Column_List" >
    id, name, credit
    </sql>
    <select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Integer" >
    select
    <include refid="Base_Column_List" />
    from course
    where id = #{id,jdbcType=INTEGER}
    </select>
    <delete id="deleteByPrimaryKey" parameterType="java.lang.Integer" >
    delete from course
    where id = #{id,jdbcType=INTEGER}
    </delete>
    <insert id="insert" parameterType="com.magicwt.bean.Course" >
    insert into course (id, name, credit
    )
    values (#{id,jdbcType=INTEGER}, #{name,jdbcType=VARCHAR}, #{credit,jdbcType=TINYINT}
    )
    </insert>
    <insert id="insertSelective" parameterType="com.magicwt.bean.Course" >
    insert into course
    <trim prefix="(" suffix=")" suffixOverrides="," >
    <if test="id != null" >
    id,
    </if>
    <if test="name != null" >
    name,
    </if>
    <if test="credit != null" >
    credit,
    </if>
    </trim>
    <trim prefix="values (" suffix=")" suffixOverrides="," >
    <if test="id != null" >
    #{id,jdbcType=INTEGER},
    </if>
    <if test="name != null" >
    #{name,jdbcType=VARCHAR},
    </if>
    <if test="credit != null" >
    #{credit,jdbcType=TINYINT},
    </if>
    </trim>
    </insert>
    <update id="updateByPrimaryKeySelective" parameterType="com.magicwt.bean.Course" >
    update course
    <set >
    <if test="name != null" >
    name = #{name,jdbcType=VARCHAR},
    </if>
    <if test="credit != null" >
    credit = #{credit,jdbcType=TINYINT},
    </if>
    </set>
    where id = #{id,jdbcType=INTEGER}
    </update>
    <update id="updateByPrimaryKey" parameterType="com.magicwt.bean.Course" >
    update course
    set name = #{name,jdbcType=VARCHAR},
    credit = #{credit,jdbcType=TINYINT}
    where id = #{id,jdbcType=INTEGER}
    </update>
    </mapper>
  3. Java客户端接口,CourseMapper.java,StudentMapper.java,ScoreMapper.java,其中CourseMapper.java提供对Course对象的增、删、查、改方法,如下所示:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    package com.magicwt.dao;

    import com.magicwt.bean.Course;

    public interface CourseMapper {
    int deleteByPrimaryKey(Integer id);

    int insert(Course record);

    int insertSelective(Course record);

    Course selectByPrimaryKey(Integer id);

    int updateByPrimaryKeySelective(Course record);

    int updateByPrimaryKey(Course record);
    }

使用所生成代码读写数据库

示例工程使用Maven构建,并使用Spring管理上下文,代码目录如图所示:
04D80B70-DB28-4373-AADD-5D0150179FB8
除MBG生成的代码和配置文件外,还需要context.xml和configuration.xml分别配置Spring和MyBatis,context.xml和configuration.xml如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd">

<!-- 配置数据库连接池 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver" />
<property name="jdbcUrl" value="jdbc:mysql://xx.xx.xx.xx:3306/test?characterEncoding=UTF-8&autoReconnect=true" />
<property name="user" value="xx" />
<property name="password" value="xx" />
<property name="initialPoolSize" value="1" />
</bean>

<!-- 配置会话工厂 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="classpath:configuration.xml" />
</bean>

<bean id="courseDao" class="org.mybatis.spring.mapper.MapperFactoryBean">
<property name="sqlSessionFactory" ref="sqlSessionFactory" />
<property name="mapperInterface" value="com.magicwt.dao.CourseMapper" />
</bean>

<bean id="studentDao" class="org.mybatis.spring.mapper.MapperFactoryBean">
<property name="sqlSessionFactory" ref="sqlSessionFactory" />
<property name="mapperInterface" value="com.magicwt.dao.StudentMapper" />
</bean>

<bean id="scoreDao" class="org.mybatis.spring.mapper.MapperFactoryBean">
<property name="sqlSessionFactory" ref="sqlSessionFactory" />
<property name="mapperInterface" value="com.magicwt.dao.ScoreMapper" />
</bean>

</beans>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>

<typeAliases>
<typeAlias alias="Course" type="com.magicwt.bean.Course"/>
<typeAlias alias="Student" type="com.magicwt.bean.Student"/>
<typeAlias alias="Score" type="com.magicwt.bean.Score"/>
</typeAliases>

<mappers>
<mapper resource="com/magicwt/mapper/CourseMapper.xml"/>
<mapper resource="com/magicwt/mapper/StudentMapper.xml"/>
<mapper resource="com/magicwt/mapper/ScoreMapper.xml"/>
</mappers>

</configuration>

编写测试类对course表执行插入操作:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class DaoTest {

private ApplicationContext context;

@Before
public void prepare() {
context = new ClassPathXmlApplicationContext(new String[] {"context.xml"});
}

@Test
public void test() {
CourseMapper courseDao = (CourseMapper) context.getBean("courseDao");
Course course = new Course();
course.setName("微积分");
course.setCredit(new Byte("4"));
courseDao.insert(course);
}

}

执行后,在course表中成功插入一条记录:
C6987E31-E4AA-4E30-85B0-74E0D4A80569