[springboot 開發單體web shop] 2. Mybatis Generator 生成common mapper

  • 2019 年 11 月 6 日
  • 筆記

Mybatis Generator tool


在我們開啟一個新項目的研發後,通常要編寫很多的entity/pojo/dto/mapper/dao..., 大多研發兄弟們都會抱怨,為什麼我要重複寫CRUD? 我們為了避免編寫一些不必要的重複程式碼,這節給大家介紹介紹使用一個開源工具,來幫助我們從這種簡單枯燥的編碼中解救出來。
隆重有請: MyBatis通用Mapper4

通用Mapper都可以極大的方便開發人員。可以隨意的按照自己的需要選擇通用方法,還可以很方便的開發自己的通用方法。
極其方便的使用MyBatis單表的增刪改查。
支援單表操作,不支援通用的多表聯合查詢。
通用 Mapper 支援 Mybatis-3.2.4 及以上版本。
Tips:
各位技術同仁一定要有版本意識哦~
Let’s code!

Create mybatis-generator-tool Module

參考上一節中的Module創建mybatis-generator-tool.


  • 添加依賴
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">      <parent>          <artifactId>expensive-shop</artifactId>          <groupId>com.life-runner</groupId>          <version>1.0-SNAPSHOT</version>      </parent>      <modelVersion>4.0.0</modelVersion>        <artifactId>mybatis-generator-tool</artifactId>        <properties>          <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>      </properties>        <build>          <plugins>              <!--springboot 構建可執行fat jars必須的插件,如不添加,在生產環境會有問題-->              <plugin>                  <groupId>org.springframework.boot</groupId>                  <artifactId>spring-boot-maven-plugin</artifactId>              </plugin>              <plugin>                  <groupId>org.mybatis.generator</groupId>                  <artifactId>mybatis-generator-maven-plugin</artifactId>                  <version>1.3.6</version>                  <configuration>                      <!-- 設置配置文件路徑 -->                      <configurationFile>                          ${basedir}/src/main/resources/generator/generatorConfig.xml                      </configurationFile>                      <!--允許覆蓋-->                      <overwrite>true</overwrite>                      <verbose>true</verbose>                  </configuration>                  <dependencies>                      <!-- mysql8 驅動-->                      <dependency>                          <groupId>mysql</groupId>                          <artifactId>mysql-connector-java</artifactId>                          <version>8.0.16</version>                      </dependency>                      <!--通用 Mapper-->                      <dependency>                          <groupId>tk.mybatis</groupId>                          <artifactId>mapper</artifactId>                          <version>4.1.5</version>                      </dependency>                  </dependencies>              </plugin>          </plugins>      </build>  </project>

  • 編寫配置文件
    根據我們在pom文件中指定的路徑:${basedir}/src/main/resources/generator/generatorConfig.xml, 我們需要在項目src=>main=>resource目錄下創建generator文件夾,在文件夾下創建文件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="generator/config.properties"/>      <context id="MysqlContext" targetRuntime="MyBatis3Simple" defaultModelType="flat">      <!--配置是否使用通用 Mapper 自帶的注釋擴展,默認 true-->      <!--<property name="useMapperCommentGenerator" value="false"/>-->        <plugin type="tk.mybatis.mapper.generator.MapperPlugin">        <!--設置Mapper生成的basic,可自定義-->        <property name="mappers" value="tk.mybatis.mapper.common.Mapper"/>        <!--大小寫轉換敏感-->        <property name="caseSensitive" value="true"/>        <!--引入lombok註解-->        <property name="lombok" value="Getter,Setter,ToString"/>        <!--分隔符定義-->        <property name="beginningDelimiter" value="`"/>        <property name="endingDelimiter" value="`"/>      </plugin>        <!-- 設置資料庫配置 -->      <jdbcConnection driverClass="${jdbc.driverClass}"        connectionURL="${jdbc.url}"        userId="${jdbc.user}"        password="${jdbc.password}">      </jdbcConnection>        <!-- 對應生成的pojo所在包 -->      <javaModelGenerator targetPackage="com.liferunner.pojo" targetProject="src/main/java"/>        <!-- 對應生成的mapper所在目錄 -->      <sqlMapGenerator targetPackage="mapper" targetProject="src/main/resources"/>        <!-- 配置mapper對應的java映射 -->      <javaClientGenerator targetPackage="com.liferunner.mapper" targetProject="src/main/java" type="XMLMAPPER"/>        <!-- 資料庫表 -->      <table tableName="carousel"></table>      <table tableName="category"></table>      <table tableName="items"></table>      <table tableName="items_comments"></table>      <table tableName="items_img"></table>      <table tableName="items_param"></table>      <table tableName="items_spec"></table>      <table tableName="order_items"></table>      <table tableName="order_status"></table>      <table tableName="orders"></table>      <table tableName="shop_users"></table>      <table tableName="user_address"></table>      <table tableName="users"></table>    </context>  </generatorConfiguration>

我們可以看到一行配置內容:<properties resource="generator/config.properties"/>,這裡是為了將我們的資料庫連接、帳號等資訊外置,配置內容如下:

jdbc.driverClass = com.mysql.cj.jdbc.Driver  jdbc.url = jdbc:mysql://localhost:3306/expensiveshop?characterEncoding=UTF-8&useSSL    =false&useUnicode=true&serverTimezone=UTC  jdbc.user = root  jdbc.password = 12345678

可以看到這裡設置的內容就是下屬程式碼中用到的。

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

配置資訊大家可以參考:傳送門


  • 使用maven測試生成
    執行以下命令:
mybatis-generator-tool>mvn mybatis-generator:generate  [INFO] Scanning for projects...  [INFO]  [INFO] ---------------< com.life-runner:mybatis-generator-tool >---------------  [INFO] Building mybatis-generator-tool 1.0-SNAPSHOT  [INFO] --------------------------------[ jar ]---------------------------------  [INFO]  [INFO] --- mybatis-generator-maven-plugin:1.3.6:generate (default-cli) @ mybatis-generator-tool ---  [INFO] Connecting to the Database  [INFO] Introspecting table carousel  [INFO] Introspecting table category  ...  [INFO] Generating Record class for table carousel  [INFO] Generating Mapper Interface for table carousel  [INFO] Generating SQL Map for table carousel  ...  [INFO] Saving file CarouselMapper.xml  ...  [INFO] Saving file Carousel.java  [INFO] Saving file Users.java  ...  [WARNING] Table configuration with catalog null, schema null, and table shop_users did not resolve to any tables  [INFO] ------------------------------------------------------------------------  [INFO] BUILD SUCCESS  [INFO] ------------------------------------------------------------------------  [INFO] Total time:  1.374 s  [INFO] Finished at: 2019-11-05T15:40:07+08:00  [INFO] ------------------------------------------------------------------------  

可以看到執行成功,雖然這裡執行成功,但是當我們打開文件的時候會發現:

package com.liferunner.pojo;    import java.util.Date;  import javax.persistence.*;  import lombok.Getter;  import lombok.Setter;  import lombok.ToString;    @Getter  @Setter  @ToString  @Table(name = "Carousel")  public class Carousel {      /**       * ����id �û�id       */      @Id      private String id;        /**       * �û��� �û���       */      private String imageUrl;      ...  }

這裡出現了亂碼問題,這又是怎麼回事呢?
沒關係,let’s bing… 傳送門,可以看到有265000條結果,那就說明我們的問題已經有太多的人遇到了,隨便點開一個:
bug1
可以看到紅框裡面的內容我們缺失了,在expensive-shopmybatis-generator-toolsrcmainresourcesgeneratorgeneratorConfig.xml中添加上 <property name="javaFileEncoding" value="UTF-8"/>,重新執行生成命令,可以看到我們的亂碼就沒有了。

@Getter  @Setter  @ToString  @Table(name = "`carousel`")  public class Carousel {      /**       * 主鍵       */      @Id      @Column(name = "`id`")      private String id;        /**       * 圖片 圖片地址       */      @Column(name = "`image_url`")      private String imageUrl;      ...

Tips:
在這一環節先劇透一個bug,否則我擔心在後續大家遇到的時候,因為它確實是和Common Mapper生成相關的。

我們點開生成的Users.java,可以看到如下所示:

@Getter  @Setter  @ToString  @Table(name = "users")  public class Users {      @Column(name = "USER")      private String user;        @Column(name = "CURRENT_CONNECTIONS")      private Long currentConnections;        @Column(name = "TOTAL_CONNECTIONS")      private Long totalConnections;  }

可是我們的Users表不是這樣的呀,這是怎麼回事???
讓我們分析分析:
1.既然沒有用到我們自己的Users表,但是又確實通過生成器生成了,那麼很明顯肯定是Mysql資料庫中表,這是肯定的。
2.那麼問題就來了,它從哪裡冒出來的?找它,盤它。
3.到底是哪個資料庫中的呢?sys?information_schema?performance_schema?
4.挨個查詢,果然:
bug2
可以看到,在performance_schema資料庫中有一個users表,那麼到底是不是我們生成出來的呢?執行SHOW CREATE TABLE users, 結果如上圖,欄位和生成出來的是一致的!
5.抓住它了,怎麼盤它???

很簡單,修改jdbc:mysql://localhost:3306/expensiveshop?nullCatalogMeansCurrent=true&characterEncoding=UTF-8&useSSL =false&useUnicode=true&serverTimezone=UTC,新增上加粗部分就可以了。

nullCatalogMeansCurrent 字面意思很簡單,就是說如果是null catalog,我就選擇current.因為mysql不支援catalog,我們需要告知mybatis這個特性,設置為true就行了。

按照SQL標準的解釋,在SQL環境下Catalog和Schema都屬於抽象概念,主要用來解決命名衝突問題。
從概念上說,一個資料庫系統包含多個Catalog,每個Catalog又包含多個Schema,而每個Schema又包含多個資料庫對象(表、視圖、序列等),反過來講一個資料庫對象必然屬於一個Schema,而該Schema又必然屬於一個Catalog,這樣我們就可以得到該資料庫對象的完全限定名稱從而解決命名衝突的問題了
從實現的角度來看,各種資料庫系統對Catalog和Schema的支援和實現方式千差萬別,針對具體問題需要參考具體的產品說明書,比較簡單而常用的實現方式是使用資料庫名作為Catalog名,Oracle使用用戶名作為Schema名.

bug2-1

可查閱Mysql官網說明:傳送門

本節我們講解了如何生成我們想要的,簡單和重要又重複的工作我們可以通過工具實現啦,下一次我們將開始實際業務的編碼實現.
gogogo.