MyBatis:使用MyBatis Generator快速完成Springboot專案資料層開發

陳正長發表於2020-10-24

使用場景

當我們使用Springboot整合Mybatis時,我們就需要為資料庫中的每一個表分別寫出:

  • 實體類
  • Mapper.xml檔案
  • Mapper介面

如果資料庫中有很多表,這個過程就會非常的繁瑣。而MyBatis官方為我們提供了MyBatis Generator外掛,我們只需要以下介紹的三個步驟就可以快速地生成以上三個檔案,極大的簡化了資料層的開發。

官網:MyBatis Generator

專案準備

以下用一個例子來演示如何在專案中使用MyBatis Generator,專案使用的環境為:

  • ubuntu 18.04
  • maven 3.6.3
  • JDK 11

專案中使用的表如圖所示

使用方法

1. 引入mybatis的依賴和MyBatis Generator外掛

在pom.xml檔案中加入以下兩個部分

mybatis的依賴:

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
</dependency>

<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.1.3</version>
</dependency>

MyBatis Generator外掛:

<plugin>
    <groupId>org.mybatis.generator</groupId>
    <artifactId>mybatis-generator-maven-plugin</artifactId>
    <version>1.4.0</version>
    <configuration>
        <overwrite>true</overwrite>
    </configuration>
</plugin>

2. MyBatis Generator 的配置檔案

MyBatis Generator配置檔案預設的路徑為

${basedir}/src/main/resources/generatorConfig.xml

所以我們在 recources 資料夾下新建 generatorConfig.xml 檔案(如果希望儲存在其他路徑可以在匯入外掛時使用 configurationFile 標籤來更改),配置檔案的內容如下:

<?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>
    <!-- JDBC 驅動的路徑,需要自己配置 -->
    <classPathEntry location="/home/XXX/.m2/repository/mysql/mysql-connector-java/8.0.21/mysql-connector-java-8.0.21.jar" />

    <context id="table" targetRuntime="MyBatis3">

        <!-- 不加註釋 -->
        <commentGenerator>
            <property name="suppressAllComments" value="true" />
        </commentGenerator>

        <jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
                        connectionURL="jdbc:mysql://localhost:3306/db?useUnicode=true&amp;characterEncoding=UTF-8&amp;serverTimezone=Asia/Shanghai"
                        userId="root"
                        password="1">
            <!-- mysql8.x需要這一行 -->
            <property name="nullCatalogMeansCurrent" value="true" />
        </jdbcConnection>

        <!-- 實體類 -->
        <javaModelGenerator targetPackage="com.example.model" targetProject="src/main/java">
            <property name="enableSubPackages" value="true" />
            <property name="trimStrings" value="true" />
        </javaModelGenerator>

        <!-- Mapper.xml檔案 -->
        <sqlMapGenerator targetPackage="com.example.mapper"  targetProject="src/main/java">
            <property name="enableSubPackages" value="true" />
        </sqlMapGenerator>

        <!-- Mapper介面檔案 -->
        <javaClientGenerator type="XMLMAPPER" targetPackage="com.example.mapper"  targetProject="src/main/java">
            <property name="enableSubPackages" value="true" />
        </javaClientGenerator>

        <table schema="db" tableName="student" domainObjectName="Student" enableCountByExample="false"
               enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false"
               selectByExampleQueryId="false" />

    </context>
</generatorConfiguration>

配置檔案需要注意的地方有以下幾點:

  1. 通過 targetPackage 和 targetProject 配置生產成的實體類、Mapper.xml檔案、Mapper介面的位置。
  2. 通過table標籤可以用來指定資料庫、表以及表對應的實體類名稱

3. 執行 Mybatis Generator

在 Maven 標籤下雙擊 generate 就可以生成對應的檔案

 可以看到相應的目錄之下出現了生成的檔案

檔案細節

開啟 StudentMapper 介面,裡面一共自動生成了六種方法

public interface StudentMapper {
    int deleteByPrimaryKey(Integer id);

    int insert(Student record);

    int insertSelective(Student record);

    Student selectByPrimaryKey(Integer id);

    int updateByPrimaryKeySelective(Student record);

    int updateByPrimaryKey(Student record);
}

insert 方法和 insertSelective 方法有什麼區別呢?

開啟 StudentMapper.xml 檔案可以看到 insertSelective 方法下用了動態SQL

(如果不記得動態SQL可以看一下這篇部落格 MyBatis:使用動態SQL簡化程式碼

<insert id="insert" parameterType="com.example.model.Student">
    insert into student (id, name, score, 
      birthday)
    values (#{id,jdbcType=INTEGER}, #{name,jdbcType=VARCHAR}, #{score,jdbcType=REAL}, 
      #{birthday,jdbcType=DATE})
  </insert>
  <insert id="insertSelective" parameterType="com.example.model.Student">
    insert into student
    <trim prefix="(" suffix=")" suffixOverrides=",">
      <if test="id != null">
        id,
      </if>
      <if test="name != null">
        name,
      </if>
      <if test="score != null">
        score,
      </if>
      <if test="birthday != null">
        birthday,
      </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="score != null">
        #{score,jdbcType=REAL},
      </if>
      <if test="birthday != null">
        #{birthday,jdbcType=DATE},
      </if>
    </trim>
  </insert>

從以上程式碼中可以看出 insertSelective 方法只新增傳入了引數的欄位,而 insert 新增所有的欄位,如果欄位有預設值,使用insert 方法就會出錯。

這種使用動態SQL的方式我們平時在寫程式碼的時候也可以使用起來。

相關文章