MyBatis學習筆記(一)簡單配置讓MyBatis跑起來
- 2020 年 4 月 3 日
- 筆記
MyBatis
是一款優秀的支援自定義SQL
查詢、存儲過程和高級映射的持久層框架,消除了幾乎多有的JDBC
程式碼和參數的手動設置和結果集的檢索。MyBatis
可以使用XML
和註解進行配置和映射,MyBatis
通過將參數映射到配置的SQL
形成最終執行的SQL
語句,最後將執行SQL
的結果映射成Java
對象返回。
一、創建Maven項目
Maven
是一個優秀的項目構建和管理工具,使用Maven
構建項目非常方便,可以非常方便地處理Jar
包依賴問題。這裡提供構建MyBatis
應用的的pom.xm
l配置內容。
<?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
以外,還引入了lombok
,lombok
是一款非常優秀的插件,它可以被安裝到Eclipse
和IntelliJ 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.java
和CountryMapper.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; }
這裡導入了lombok
的Data
註解,在運行時會自動為實體類創建getter
和setter
方法。本例中沒有創建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.xml
中id="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
的學習筆記,歡迎閱讀,我們共同進步。