淺析MyBatis(四):全自動寫代碼的MyBatis逆向工程


在前面幾篇文章中,筆者介紹了 MyBatis 的運行流程,在此基礎上簡單介紹了手寫 MyBatis 簡易框架自定義 MyBatis 插件的步驟,相信大家對於 MyBatis 框架的使用流程已經游刃有余了。然而,面對實際開發過程中大量的數據庫表單,傳統的 MyBatis 使用步驟已經顯得繁瑣不堪,本文介紹的就是利用 MyBatis 逆向工程把 MyBatis 框架使用的前期配置准備工作交給代碼生成器完成,從而節省時間提高開發效率。本文涉及到的代碼已上傳至 GitHub: 🔗mybatis-generator-demo

話不多說,現在開始🔛🔛🔛!

1. MyBatis逆向工程簡介

所謂 MyBatis 逆向工程,就是 MyBatis 根據數據庫中已經設計好的表單自動生成 domain、mapper、mapper.xml 以及 example 類(用於添加條件),從而大大提高開發效率。在實際開發中,只要敲定了數據庫的表結構就可以通過 MyBatis 逆向工程生成表單對應的基本配置,省去了手動寫 mapper 的工作,然后就可以根據實際業務需求來進行進一步的開發。下面將介紹 MyBatis 的官方生成器插件 MyBatis Generator 以及用戶 itfsw 在 GitHub 開源的一個特別好用的生成器增強插件 mybatis-generator-plugin

2. MyBatis逆向工程插件

2.1 MBG插件簡介

MyBatis 提供了官方的代碼生成器 MyBatis Generator(MBG),能夠為所有版本的 MyBatis 以及 2.2.0 之后的 iBatis 版本生成代碼。官方的 MBG 插件能夠生成與數據庫進行簡單交互的 CRUD 操作,在使用時需要在 pom.xml 文件中引入插件的依賴:

<plugin>
  <groupId>org.mybatis.generator</groupId>
  <artifactId>mybatis-generator-maven-plugin</artifactId>
  <version>1.3.7</version>
</plugin>

2.2 MBG增強插件簡介

在 MyBatis 的官方 MBG 插件的基礎上,有很多開發者開發了優秀的增強插件並發布在 GitHub 上。本節中介紹的就是用戶 itfsw 開發的 MBG 的增強插件,詳情可見:https://github.com/itfsw/mybatis-generator-plugin 。這是一個 MBG 插件的拓展插件包,方便和減少了代碼開發量。該插件集成了查詢單條數據插件(SelectOneByExamplePlugin)、MySQL分頁插件(LimitPlugin)、數據Model鏈式構建插件(ModelBuilderPlugin)、Example Criteria 增強插件(ExampleEnhancedPlugin)、Example 目標包修改插件(ExampleTargetPlugin)、批量插入插件(BatchInsertPlugin)、邏輯刪除插件(LogicalDeletePlugin)、數據Model屬性對應Column獲取插件(ModelColumnPlugin)、存在即更新(UpsertPlugin)等等插件。在實際項目中使用時需要引入插件的依賴:

<dependency>
  <groupId>com.itfsw</groupId>
  <artifactId>mybatis-generator-plugin</artifactId>
  <version>1.3.2</version>
</dependency>

3. MyBatis逆向工程實踐

在介紹了兩款與 MyBatis 逆向工程相關的插件之后,下面將通過一個實際項目來實踐 MyBatis 的逆向工程。

3.1 前期准備

3.1.1 構建SpringBoot項目並集成MyBatis

本文中采用 SpringBoot + MyBatis 來構建項目,這種構建方式也是目前實際開發中常用的方式。項目構建完成后新建對應的 package 用於存放生成器生成的代碼,如下圖所示。

在上圖中,domain 文件夾用於存放根據數據庫表單生成的 POJO 類,mapper 文件夾用於存放生成器生成的表單對應的接口,而在文件夾 resoucres/mapper 下存放的是生成的 mapper 接口對應的 xml 配置文件。

3.1.2 配置pom.xml文件

進一步需要在 pom.xml 文件中配置項目相關的 MBG 依賴、MySQL 依賴、Lombok 依賴等等,如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  
  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.4.3</version>
    <relativePath/> <!-- lookup parent from repository -->
  </parent>

  <groupId>com.chiaki</groupId>
  <artifactId>mybatis-generator-demo</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>
  <name>mybatis-generator-demo</name>
  <description>Demo project for Spring Boot</description>

  <properties>
    <java.version>1.8</java.version>
  </properties>

  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!--lombok插件-->
    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <optional>true</optional>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.42</version>
    </dependency>
    <dependency>
      <groupId>org.mybatis.spring.boot</groupId>
      <artifactId>mybatis-spring-boot-starter</artifactId>
      <version>2.0.0</version>
    </dependency>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <scope>test</scope>
    </dependency>
  </dependencies>

  <build>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
        <configuration>
          <excludes>
            <exclude>
              <groupId>org.projectlombok</groupId>
              <artifactId>lombok</artifactId>
            </exclude>
          </excludes>
        </configuration>
      </plugin>
      <plugin>
        <!--MBG插件-->
        <groupId>org.mybatis.generator</groupId>
        <artifactId>mybatis-generator-maven-plugin</artifactId>
        <version>1.3.7</version>
        <configuration>
          <!-- 是否覆蓋,true表示會替換生成的Java文件,false則不覆蓋 -->
          <overwrite>true</overwrite>
          <verbose>true</verbose>
        </configuration>
        <dependencies>
          <!--mysql驅動包-->
          <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.42</version>
          </dependency>
          <!-- MBG擴展包 -->
          <dependency>
            <groupId>com.itfsw</groupId>
            <artifactId>mybatis-generator-plugin</artifactId>
            <version>1.3.2</version>
          </dependency>
        </dependencies>
      </plugin>
    </plugins>
  </build>
</project>

3.1.3 配置application.yml文件

接下來需要配置 SpringBoot 項目的 application.yml 配置文件,如下所示:

# spring配置
spring:
  # 數據庫配置
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/mybatis_generator_demo?useUnicode=true&characterEncoding=utf-8
    username: root
    password: admin

# mybatis配置
mybatis:
  # 指定xml文件的位置
  mapper-locations: classpath:mapper/*.xml
  # 指定domain文件的位置
  type-aliases-package: com.chiaki.domain
  # 添加日志實現類以打印日志
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

# 服務器配置
server:
  # 指定端口
  port: 8079

在 SpringBoot 集成 MyBatis 的項目中,只需要將 MyBatis 的相關配置寫道 SpringBoot 的配置文件中即可。如上圖所示,配置相應的 MySQL 數據源以及相應的 MyBatis 設置以及指定訪問端口。

3.1.4 准備數據庫表單

准備逆向工程需要的表單,這里准備 student_info 以及 class_info 兩張表,如下所示:

CREATE DATABASE /*!32312 IF NOT EXISTS*/`mybatis_generator_demo` /*!40100 DEFAULT CHARACTER SET utf8 */;

/*Table structure for table `class_info` */

DROP TABLE IF EXISTS `class_info`;

CREATE TABLE `class_info` (
  `class_id` int(10) NOT NULL COMMENT '班級ID',
  `class_name` varchar(20) DEFAULT NULL COMMENT '班級名稱',
  PRIMARY KEY (`class_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

/*Data for the table `class_info` */

insert  into `class_info`(`class_id`,`class_name`) values 
(202101,'A班'),
(202102,'B班'),
(202103,'C班');

/*Table structure for table `student_info` */

DROP TABLE IF EXISTS `student_info`;

CREATE TABLE `student_info` (
  `id` int(10) NOT NULL AUTO_INCREMENT COMMENT '學生ID',
  `name` varchar(20) DEFAULT NULL COMMENT '姓名',
  `sex` varchar(20) DEFAULT NULL COMMENT '性別',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;

/*Data for the table `student_info` */

insert  into `student_info`(`id`,`name`,`sex`) values 
(1,'張三','男'),
(2,'托尼·李四','男'),
(3,'王五','女'),
(4,'趙六','男');

3.2 編寫MBG配置文件

3.2.1 配置generatorConfig.xml文件

做好以上配置之后就來到最為關鍵的一步,即編寫逆向工程需要的 generatorConfig.xml 生成器配置文件,如下所示。在實際開發中可以借鑒官網的 MyBatis Generator 配置文件以及自己的業務需求自行編寫。

<?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="Tables" targetRuntime="MyBatis3">

    <!-- 批量插入插件 -->
    <plugin type="com.itfsw.mybatis.generator.plugins.BatchInsertPlugin">
      <property name="allowMultiQueries" value="false"/>
    </plugin>

    <!--重命名查詢class名稱-->
    <plugin type="org.mybatis.generator.plugins.RenameExampleClassPlugin" >
      <property name="searchString" value="Example$"/>
      <property name="replaceString" value="Criteria"/>
    </plugin>

    <!-- 查詢單條數據插件 -->
    <plugin type="com.itfsw.mybatis.generator.plugins.SelectOneByExamplePlugin"/>

    <!-- MySQL分頁插件 -->
    <plugin type="com.itfsw.mybatis.generator.plugins.LimitPlugin">
      <!-- 通過配置startPage影響Example中的page方法開始分頁的頁碼,默認分頁從0開始 -->
      <property name="startPage" value="1"/>
    </plugin>

    <!-- 自定義注釋插件 -->
    <plugin type="com.itfsw.mybatis.generator.plugins.CommentPlugin">
      <!-- 自定義模板路徑 -->
      <property name="template" value="src/main/resources/mybatis-generator-comment.ftl" />
    </plugin>

    <!-- Lombok插件 -->
    <plugin type="com.itfsw.mybatis.generator.plugins.LombokPlugin">
      <!-- @Builder 必須在 Lombok 版本 >= 1.18.2 的情況下 -->
      <property name="@Builder" value="false"/>
      <!-- @NoArgsConstructor 和 @AllArgsConstructor 使用規則和Lombok一致 -->
      <property name="@AllArgsConstructor" value="false"/>
      <property name="@NoArgsConstructor" value="false"/>
    </plugin>

    <!-- xml重新生成時覆蓋 -->
    <plugin type="org.mybatis.generator.plugins.UnmergeableXmlMappersPlugin"/>

    <!-- 注釋 -->
    <commentGenerator>
      <property name="javaFileEncoding" value="UTF-8"/>
    </commentGenerator>

    <!-- JDBC連接 -->
    <jdbcConnection
        driverClass="com.mysql.jdbc.Driver"
        connectionURL="jdbc:mysql://localhost:3306/mybatis_generator_demo?useUnicode=true&amp;characterEncoding=utf-8&amp;serverTimezone=GMT%2B8"
        userId="root"
        password="admin">
      <!-- 針對mysql數據庫 -->
      <property name="useInformationSchema" value="true"/>
    </jdbcConnection>

    <!-- 非必需,類型處理器,在數據庫類型和java類型之間的轉換控制-->
    <!-- 默認false,把JDBC DECIMAL 和 NUMERIC 類型解析為 Integer,為 true時把JDBC DECIMAL 和
     NUMERIC 類型解析為java.math.BigDecimal -->
    <javaTypeResolver>
      <!-- 是否使用bigDecimal, false可自動轉化以下類型(Long, Integer, Short, etc.) -->
      <property name="forceBigDecimals" value="false" />
    </javaTypeResolver>

    <!-- domain領域模型  其中targetPackage需要根據你自己創建的目錄進行改動 -->
    <javaModelGenerator targetPackage="com.chiaki.mybatisgeneratordemo.domain" targetProject="src/main/java">
      <!-- 從數據庫返回的值被清理前后的空格 -->
      <property name="trimStrings" value="true" />
      <!-- enableSubPackages:是否讓schema作為包的后綴 -->
      <property name="enableSubPackages" value="true" />
    </javaModelGenerator>

    <!-- mapper xml文件 -->
    <sqlMapGenerator targetPackage="mapper"  targetProject="src/main/resources">
      <!-- enableSubPackages:是否讓schema作為包的后綴 -->
      <property name="enableSubPackages" value="true" />
    </sqlMapGenerator>

    <!-- Mapper接口 -->
    <javaClientGenerator targetPackage="com.chiaki.mybatisgeneratordemo.mapper" targetProject="src/main/java" type="XMLMAPPER">
      <property name="enableSubPackages" value="true" />
    </javaClientGenerator>

    <!-- 配置表信息 -->
    <!-- tableName為對應的數據庫表 -->
    <table tableName="student_info">
      <property name="useActualColumnNames" value="false"/>
      <generatedKey column="id" sqlStatement="Mysql" identity="true" />
    </table>

    <table tableName="class_info">
      <property name="useActualColumnNames" value="false"/>
      <generatedKey column="id" sqlStatement="Mysql" identity="true" />
    </table>

  </context>
</generatorConfiguration>

3.2.2 配置mybatis-generator-comment.ftl文件

在上述配置文件中,我們使用了 itfsw 的 MBG 增強插件,其中包括自定義的注釋插件,其配置如下所示。具體的配置細節可參考 itfsw 的 Github 對應的項目

<?xml version="1.0" encoding="UTF-8"?>
<template>
    <!-- 調用此方法可將文件級注釋添加到生成的Java文件中 -->
    <comment ID="addJavaFileComment"></comment>
    <comment ID="addComment"></comment>
    <comment ID="addRootComment"></comment>
    <!-- 將數據庫表字段的注釋添加到相應實體的變量上 -->
    <comment ID="addFieldComment">
        <![CDATA[
        <#if introspectedColumn??>
            <#if introspectedColumn.remarks?? && introspectedColumn.remarks != ''>
                <#list introspectedColumn.remarks ? split("\n") as remark>
                    /**  ${remark}  **/
                </#list>
            </#if>
        </#if>
        ]]>
    </comment>
    <!-- 為模型類添加注釋 -->
    <comment ID="addModelClassComment">
        <![CDATA[
        <#if introspectedTable.remarks?? && introspectedTable.remarks != ''>
            <#list introspectedTable.remarks?split("\n") as remark>
                /**
                * ${remark}
                **/
            </#list>
        </#if>

        ]]>
    </comment>
    <!-- 為內部類添加注釋 -->
    <comment ID="addClassComment">
        <![CDATA[
        /**
        * ${introspectedTable.fullyQualifiedTable}
        **/
        ]]>
    </comment>

    <comment ID="addEnumComment"></comment>
    <comment ID="addInterfaceComment"></comment>
    <comment ID="addGetterComment"></comment>
    <comment ID="addSetterComment"></comment>
    <comment ID="addGeneralMethodComment"></comment>
</template>

3.3 運行MBG生成器生成代碼

在設置好上述的配置文件之后,就可以執行 maven 命令開始生成代碼了,這里可以通過 maven 命令生成:

mvn mybatis-generator:generate

也可以找到 maven 插件雙擊生成:

運行之后可以在目錄中看到已經生成的代碼文件,如下所示:

3.4 生成代碼測試

生成代碼后編寫相應的測試類 testQuery 對生成的代碼進行測試,如下所示:

@RunWith(SpringRunner.class)
@SpringBootTest()
public class testQuery {

  // mapper注入
  @Resource
  StudentInfoMapper studentInfoMapper;
  @Resource
  ClassInfoMapper classInfoMapper;

  @Test
  public void testQueryStudentInfo() {
    // 測試根據主鍵查找學生信息
    StudentInfo studentInfo = studentInfoMapper.selectByPrimaryKey(2);
    System.out.println(studentInfo);
  }

  @Test
  public void testQueryStudentInfoByConditions() {
    // 增強查詢
    StudentInfoCriteria studentInfoCriteria = new StudentInfoCriteria();
    // 條件組合
    studentInfoCriteria.createCriteria()
        // id字段在{1, 3, 4}當中
        .andIdIn(Arrays.asList(1, 3, 4))
        // sex = "男"
        .andSexEqualTo("男");
    // 得到查詢結果列表
    List<StudentInfo> studentInfos = studentInfoMapper.selectByExample(studentInfoCriteria);
    System.out.println(studentInfos);
    ClassInfoCriteria classInfoCriteria = new ClassInfoCriteria();
    // 查詢條件:class_id = 202101
    classInfoCriteria.createCriteria().andClassIdEqualTo(202101);
    // 得到查詢結果
    List<ClassInfo> classInfos = classInfoMapper.selectByExample(classInfoCriteria);
    System.out.println(classInfos);
  }
}

如上所示編寫了查詢 student_info 與 class_info 表的測試方法,可以看出 MyBatis 逆向工程生成的代碼可以包含了基本查詢方法,同時也支持組合條件進行查詢。在運行測試方法前,還需要再 SpringBoot 項目的啟動類上加入 @MapperScan("com.chiaki.mybatisgeneratordemo.mapper") 來掃描 mapper 接口。然后運行測試方法得到如下結果:

從運行結果來看,逆向工程生成的代碼能夠經得起檢驗,測試結果也完全正確。

總結

本文首先介紹了 MyBatis 逆向工程的概念,然后介紹了與逆向工程相關的 MBG 插件與增強插件,最后通過一個 SpringBoot 集成 MyBatis 的項目進行了逆向工程的實踐並取得了正確的效果。在當今的互聯網開發中,時間就是效率,如果只會簡單的 CRUD 操作恐怕已經無法滿足企業對后端開發工程師的要求,因此需要掌握這種自動生成代碼的技巧,同時加油不斷提升自己!

參考資料

MBG 官方社區:http://mybatis.org/generator/

iffsw 增強插件項目:https://github.com/itfsw/mybatis-generator-plugin

淺析MyBatis(一):由一個快速案例剖析MyBatis的整體架構與運行流程

淺析MyBatis(二):手寫一個自己的MyBatis簡單框架

淺析MyBatis(三):聊一聊MyBatis的實用插件與自定義插件

🔚🔚🔚

覺得有用的話就點個推薦吧~


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM