MyBatis學習筆記(一)簡單配置讓MyBatis跑起來

MyBatis是一款優秀的支援自定義SQL查詢、存儲過程和高級映射的持久層框架,消除了幾乎多有的JDBC程式碼和參數的手動設置和結果集的檢索。MyBatis可以使用XML和註解進行配置和映射,MyBatis通過將參數映射到配置的SQL形成最終執行的SQL語句,最後將執行SQL的結果映射成Java對象返回。

一、創建Maven項目

Maven是一個優秀的項目構建和管理工具,使用Maven構建項目非常方便,可以非常方便地處理Jar包依賴問題。這裡提供構建MyBatis應用的的pom.xml配置內容。

<?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">      <modelVersion>4.0.0</modelVersion>        <groupId>com.lemon</groupId>      <artifactId>lemon-mybatis</artifactId>      <version>1.0-SNAPSHOT</version>        <properties>          <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>          <mybatis.version>3.4.6</mybatis.version>          <junit.version>4.12</junit.version>          <mysql.connector.version>8.0.11</mysql.connector.version>          <slf4j.version>1.7.25</slf4j.version>          <log4j.version>1.2.17</log4j.version>          <lombok.version>1.16.20</lombok.version>      </properties>        <dependencies>            <!-- mybatis核心依賴 -->          <dependency>              <groupId>org.mybatis</groupId>              <artifactId>mybatis</artifactId>              <version>${mybatis.version}</version>          </dependency>            <!-- 測試依賴 -->          <dependency>              <groupId>junit</groupId>              <artifactId>junit</artifactId>              <version>${junit.version}</version>              <scope>test</scope>          </dependency>            <!-- mysql資料庫連接依賴 -->          <dependency>              <groupId>mysql</groupId>              <artifactId>mysql-connector-java</artifactId>              <version>${mysql.connector.version}</version>          </dependency>            <!-- 日誌模組 -->          <dependency>              <groupId>org.slf4j</groupId>              <artifactId>slf4j-api</artifactId>              <version>${slf4j.version}</version>          </dependency>            <dependency>              <groupId>org.slf4j</groupId>              <artifactId>slf4j-log4j12</artifactId>              <version>${slf4j.version}</version>              <scope>test</scope>          </dependency>            <dependency>              <groupId>log4j</groupId>              <artifactId>log4j</artifactId>              <version>${log4j.version}</version>          </dependency>            <dependency>              <groupId>org.projectlombok</groupId>              <artifactId>lombok</artifactId>              <version>${lombok.version}</version>          </dependency>        </dependencies>        <build>          <plugins>              <plugin>                  <groupId>org.apache.maven.plugins</groupId>                  <artifactId>maven-compiler-plugin</artifactId>                  <version>3.7.0</version>                  <configuration>                      <source>1.8</source>                      <target>1.8</target>                      <encoding>UTF-8</encoding>                  </configuration>              </plugin>          </plugins>      </build>  </project>

其中<properties>標籤指定了源程式碼的編碼方式為UTF-8,以及項目所依賴的Jar包的版本。除了引入MyBatis應用所必須的Jar以外,還引入了lomboklombok是一款非常優秀的插件,它可以被安裝到EclipseIntelliJ IDEA上,使用lombok的相關註解可以使得創建JavaBean的程式碼十分簡潔,至於如何使用,可以去CSDN上找到相關部落格學習一下。

二、準備資料庫

這裡準備一個非常簡單的MySQL資料庫,資料庫的編碼方式設置為UTF-8,現在提供相關的SQL語句來建立資料庫並插入測試數據。

-- 創建名稱為lemon-mybatis的資料庫  CREATE DATABASE lemon-mybatis DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;  -- 使用資料庫  use lemon-mybatis;  -- 創建資料庫表並插入數據  DROP TABLE IF EXISTS `country`;  CREATE TABLE `country` (    `id` int(11) NOT NULL AUTO_INCREMENT,    `countryName` varchar(255) DEFAULT NULL,    `countryCode` varchar(255) DEFAULT NULL,    PRIMARY KEY (`id`)  );  INSERT `country` (`countryName`, `countryCode`)  VALUES ('中國', 'CN'), ('美國', 'US'),  		('俄羅斯', 'RU'), ('英國', 'GB'), ('法國', 'FR');

三、配置MyBatis

配置MyBatis的方式有多種,最常見的是使用XML形式進行配置,當然,與Spring進行整合的時候,也可以使用Spring Bean的方式進行配置,另外還可以通過Java編碼方式進行配置,但是這種方式不常用,這裡僅僅使用XML形式配置MyBatis。 在項目的src/main/resources文件夾下面創建mybatis-config.xml配置文件,具體配置的內容如下:

<?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>        <settings>          <!-- 配置日誌實現 -->          <setting name="logImpl" value="LOG4J"/>      </settings>        <!-- 配置實體類包名 -->      <typeAliases>          <package name="com.lemon.example.model"/>      </typeAliases>        <environments default="development">          <environment id="development">              <!-- 配置默認事務管理器 -->              <transactionManager type="JDBC">                  <property name="" value=""/>              </transactionManager>              <dataSource type="UNPOOLED">                  <property name="driver" value="com.mysql.cj.jdbc.Driver"/>                  <property name="url" value="jdbc:mysql://192.168.171.133:3306/lemon-mybatis?useSSL=false"/>                  <property name="username" value="root"/>                  <property name="password" value="123456"/>              </dataSource>          </environment>      </environments>      <mappers>          <!-- 當沒有寫Mapper對應的介面時候,需要在這裡配置XML文件位置,且標籤mapper必須有在package前面 -->          <mapper resource="com/lemon/example/mapper/CountryMapper.xml"/>      </mappers>  </configuration>

簡單介紹一下這個配置文件:

  • <settings>中的logImpl屬性配置指定使用LOG4J輸出日誌
  • <typeAliases>配置了一個包的別名,通常情況下,辨別一個類使用的是類的全限定名稱,比如com.lemon.example.model.Country,在Mybatis中會頻繁使用到類的全限定名稱,所以配置包的別名以後,在配置文件中需要使用到全限定名稱的時候直接寫簡單的類名即可,如Country
  • <environments>環境配置中主要配置了資料庫連接,可以同時配置多個資料庫連接環境,內部使用<environment>隔離不同的環境。
  • <mappers>標籤是配置配置Mapper文件的標籤,其內部可以配置多個多個類似CountryMapper.xml,使用的是<mapper>標籤,也可以使用<package>標籤,更加便捷,後面會介紹更多細節。

四、創建實體類和Mapper.xml文件

MyBatis是一個結果映射型框架,一般在資料庫設計和實體類設計的過程中,都是一個表對應一個實體類,對資料庫的增刪改查一般都是將實體類作為數據載體。而這裡的Mapper.xml文件,是SQL語句和結果映射的基本載體,一般的命名習慣是實體類的名稱加上Mapper,比如CountryMapper.xml。在實際的開發過程中,一個實體類Country對應一個介面CountryMapper.javaCountryMapper.xml文件,其中介面CountryMapper.java放在src/main下面的包里,比如com.lemon.example.mapper,而CountryMapper.xml文件則放在src/main/resources文件夾下,建立的各層文件夾和對應的介麵包名一致,如com/lemon/example/mapper,其中介面並不是必須的。 本例中實體類Country的程式碼為:

package com.lemon.example.model;    import lombok.Data;    /**   * @author lemon   * @date 2018/4/22 下午9:32   */  @Data  public class Country {        private Long id;      private String countryName;      private String countryCode;    }

這裡導入了lombokData註解,在運行時會自動為實體類創建gettersetter方法。本例中沒有創建CountryMapper介面,所以直接創建CountryMapper.xml文件,程式碼如下:

<?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.lemon.example.mapper.CountryMapper">      <select id="selectAll" resultType="Country">          select id, countryName, countryCode from country      </select>  </mapper>

對於上面的Mapper文件,進行如下解釋:

  • 標籤<mapper>XML的根元素,屬性namespace定義了當前XML的命名空間,是唯一的,如果沒有創建該Mapper文件的Mapper介面,那麼這個命名空間可以隨意設置,如果創建了介面,那麼這個命名空間的值必須是對應介面的全限定類名。
  • 標籤<select>是定義查詢的語句的標籤,它的屬性id是該標籤的標識,是唯一的,如果該Mapper文件有對應的介面,那麼id是對應介面的方法名稱,屬性resultType是描述查詢結果映射到哪個實體類中,由於在mybatis-config.xml文件中配置了別名,所以這裡僅僅需要寫Country(不區分大小寫,但是為了統一,建議和類名一致)即可,否則將需要寫全限定類名com.lemon.example.model.Country

五、配置Log4j日誌文件

對於項目的開發,一看都要量身訂製日誌文件,以便調優,這裡將在src/main/resources文件夾下建立log4j.properties文件,程式碼如下:

# 全局配置  log4j.rootLogger=ERROR, stdout  # Mybatis日誌配置  log4j.logger.com.lemon.example.mapper=TRACE  # 控制台輸出配置  log4j.appender.stdout=org.apache.log4j.ConsoleAppender  log4j.appender.stdout.layout=org.apache.log4j.PatternLayout  log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

日誌的全局配置是Error級別的,設置的是控制台輸出,這是最簡單的設置,也是開發階段比較實用的設置。Mybatis日誌配置指定了包名com.lemon.example.mapper,它對應的是介面,TRACE是最低級別的日誌,這可以使得SQL語句執行的資訊也會被列印出來。控制台輸出配置了控制台日誌列印的基本格式。

六、編寫測試程式碼

本篇文章是一個入門案例,介紹了Mybatis最基本的配置,接下來編寫一個測試程式碼,看看程式碼的運行效果。測試程式碼一般在Maven項目中都是寫在src/test/java下的包中的,建立包com.lemon.example.mapper,並在該包下創建基礎測試類BaseMapperTest,程式碼如下:

package com.lemon.example.mapper;    import org.apache.ibatis.io.Resources;  import org.apache.ibatis.session.SqlSession;  import org.apache.ibatis.session.SqlSessionFactory;  import org.apache.ibatis.session.SqlSessionFactoryBuilder;  import org.junit.BeforeClass;    import java.io.IOException;  import java.io.Reader;    /**   * 測試基礎類   *   * @author lemon   * @date 2018/5/20 下午11:37   */  public class BaseMapperTest {        private static SqlSessionFactory sqlSessionFactory;        @BeforeClass      public static void init() {          try {              Reader reader = Resources.getResourceAsReader("mybatis-config.xml");              sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);              reader.close();          } catch (IOException e) {              e.printStackTrace();          }      }        public SqlSession getSqlSession() {          return sqlSessionFactory.openSession();      }  }

這是一個基礎類,主要負責載入mybatis-config.xml來創建SqlSession實例對象,因為後期會有很多測試,如果每個測試都要重複編寫獲取SqlSession實例對象的程式碼,就顯得有些多餘了,這裡進行了基本的程式碼重構復用。對於CountryMapper的測試,程式碼如下:

package com.lemon.example.mapper;    import com.lemon.example.model.Country;  import org.apache.ibatis.session.SqlSession;  import org.junit.Test;    import java.util.List;    /**   * @author lemon   * @date 2018/5/8 下午5:22   */  public class CountryMapperTest extends BaseMapperTest {        @Test      public void testSelectAll() {          try (SqlSession sqlSession = getSqlSession()) {              List<Country> countryList = sqlSession.selectList("com.lemon.example.mapper.CountryMapper.selectAll");              printCountryList(countryList);          }      }        private void printCountryList(List<Country> countryList) {          for (Country country : countryList) {              System.out.printf("%-4d%4s%4sn", country.getId(), country.getCountryName(), country.getCountryCode());          }      }  }

對上面兩段程式碼進行如下解釋:

  • 通過Resources工具類將mybatis-config.xml配置讀入Reader
  • 再通過SqlSessionFactoryBuilder建造類使用Reader創建SqlSessionFactory工廠對象,在創建SqlSessionFactory工廠對象過程中,首先會解析mybatis-config.xml配置文件,解析完成之後,SqlSessionFactory工廠對象就包含了所有的屬性配置和執行SQL的資訊。
  • 通過繼承BaseMapperTest類,直接調用父類的getSqlSession方法可以直接獲取SqlSession對象。
  • 通過SqlSession的selectList方法查找到CountryMapper.xmlid="selectAll"方法,執行SQL語句,MyBatis底層使用JDBC執行SQL語句,並將查詢到的結果集ResultSet後,根據resultType的配置將結果映射到Country類型的集合中,返回查詢結果。
  • 最後將查詢到的結果按照指定的格式進行輸出到控制台。記得要關閉SqlSession,常見的做法是將其寫在finally塊中,但是程式碼中使用的是JDK1.7的新特性,直接寫在try後面的圓括弧裡面,資源在利用完畢之後會自動關閉,這樣做程式碼更加簡潔。

執行測試程式碼,輸出的日誌如下所示:

DEBUG [main] - ==>  Preparing: select id, countryName, countryCode from country  DEBUG [main] - ==> Parameters:  TRACE [main] - <==    Columns: id, countryName, countryCode  TRACE [main] - <==        Row: 1, 中國, CN  TRACE [main] - <==        Row: 2, 美國, US  TRACE [main] - <==        Row: 3, 俄羅斯, RU  TRACE [main] - <==        Row: 4, 英國, GB  TRACE [main] - <==        Row: 5, 法國, FR  DEBUG [main] - <==      Total: 5  1     中國  CN  2     美國  US  3    俄羅斯  RU  4     英國  GB  5     法國  FR

這篇博文僅僅是對Mybatis進行了一個簡單的案例實戰,後面會繼續發布多篇Mybatis的學習筆記,歡迎閱讀,我們共同進步。