來源:TheAlchemist 鏈接:www.jianshu.com/p/1c7c7d1bba33
MyBatis作爲一個輕量的SQL映射框架,確實很簡單,但是知識點挺多,實際使用中還是會有時想不起來某個標籤該怎麼寫,所以整理了這篇文章,以備查詢。由於MyBatis如此簡單,使得這一篇文章基本把實際使用中常碰到的事情都涵蓋了,包括:
- MyBatis中的一些概念
- MyBatis包含的內容
- SQL映射
- 動態SQL
一、 MyBatis中的一些概念
MyBatis的架構
1. MyBatis是個什麼東西
在使用MyBatis的項目裏,日誌中往往會出現很多拼接SQL語句的log,這其實說明了MyBatis底層還是使用JDBC來實現的。在JDBC的基礎上,爲了性能考慮,所有的語句都是基於SqlSession。顧名思義,維護這個類的實例其實就是維護了一個對於某個數據庫的連接的會話,在這個會話裏可以有緩存啊什麼之類的。
2. mapper接口是怎麼映射成SQL語句的
目前多數開發者還是會使用XML來進行MyBatis的配置,包括MyBatis的核心配置和SQL映射配置。其實和註解一樣,XML本身只不過是一個元數據的載體,最終起作用的還是MyBatis的核心類。其中有這樣幾個比較重要的:
- SqlSessionFactoryBuilder,用來創建SqlSessionFactory的實例,之後就沒有用了,其生命週期只是在初始化的時候有作用。
- SqlSessionFactory,MyBatis最基礎的類,用來創建會話(即SqlSession的實例),其生命週期與整個系統的生命週期相同,在系統運行的任何時候都可以使用它查詢到當前數據庫的配置信息等。
- SqlSession,真正的和數據庫之間的會話,線程不安全,所以其生命週期和使用它的線程相同。
- 各種Mapper,承載了實際的業務邏輯,其生命週期比較短,由SqlSession創建。
3. Spring環境中MyBatis的初始化過程
實際情況中MyBatis往往是在Spring的環境中使用的,MyBatis本身並不依賴Spring,但是使用Spring可以極大的提高開發效率,由於Spring進行了控制反轉,所以其中MyBatis的初始化過程和正常過程稍稍有些不同:
- Spring發現需要創建SqlSessionFactory實例,會在classpath下找到MyBatis的核心配置文件,使用它來初始化一個SqlSessionFactory實例。當然,這一步完全可以使用代碼來完成,或者使用註解,就更加清晰明瞭。
- 往往mapper類也會作爲bean注入到代碼中去的,那麼Spring會使用上一步中的SqlSessionFactory實例來創建SqlSession的實例。
- 然後再使用SqlSession嘗試創建各個mapper對象。
- 於此同時,MyBatis會掃描classpath下的mapper映射XML文件(此路徑可以自定義),對於每一個mapper接口,它的「類全名」會作爲命名空間,來和映射文件中的mapper標籤進行匹配。
- 對於每一個映射文件中的一個執行語句標籤(如select、delete),MyBatis會把他們映射到SqlSession的方法上,創建mapper接口的一個實現類。
- 如果mapper接口和其映射文件一一匹配,則bean創建成功。
二、MyBatis包含的內容
MyBatis本身就是一個簡單的ORM框架,提供了SQL語句到方法、關係型數據表到對象的映射。實際使用中與開發者相關的有兩個東西:
- MyBatis核心配置 緩存、數據源、日誌等關係到MyBatis其本身行爲的一些配置。
- mapper接口的映射 針對於具體業務邏輯的SQL映射。
三、SQL映射
MyBatis也可以使用註解來實現映射,對於簡單的語句,使用註解可能會更加清晰簡單,但是其真正強大的地方還是XML。
1. select
屬性 | 描述 |
---|---|
id | 此命名空間內的標識符 |
parameterType | 參數的類的全名或者alias,可選。默認爲空。 |
parameterMap | Deprecated |
resultType | 返回結果的類型全名或alias,如果結果是集合,此類型表示的是集合的成員類型。 |
resultMap | 使用指定的resultMap來映射結果集。resultMap 和 resultType只能二選一。 |
flushCache | 如果爲true,每次調用,一級緩存和二級緩存都會回寫。select語句中默認爲false。 |
useCache | 如果爲true,結果將在二級緩存中緩存。select語句中默認爲true |
timeout | 設置超時,若超時則拋出異常。 |
fetchSize | 嘗試在獲取數據時分批獲取。 |
statementType | STATEMENT,PREPARED或者CALLABLE. 分別對應JDBC中的Statement,PreparedStatement和CallableStatement respectively。默認PREPARED. |
resultSetType | FORWARD_ONLY,SCROLL_SENSITIVE或者SCROLL_INSENSITIVE。默認爲空。 |
databaseId | 使用特定的databaseIdProvider |
resultOrdered | 嵌套查詢時使用。 |
resultSets | 多返回集合時使用。 |
2. 修改語句(insert,update,DELETE)
這3種語句的屬性基本和上邊select的一樣,INSERT和UPDATE的語句有幾個特殊的屬性如下:
屬性 | 描述 |
---|---|
useGeneratedKeys | 將使用JDBC的getGeneratedKeys方法來獲取主鍵的值。默認爲false。 |
keyProperty | 主鍵。MyBatis會將生成的主鍵賦給這個列。聯合主鍵使用逗號隔開。 |
keyColumn | 特定數據庫需要使用。 |
3. SQl語句段(sql標籤)
標籤可以定義一段sql語句段,可以在其他語句中引入使用。sql標籤可以包含參數。示例如下:
<sql id="userColumns">${alias}.id,${alias}.username,${alias}.password </sql> <select id="selectUsers" resultType="map"> select <include refid="userColumns"><property name="alias" value="t1"/></include>, <include refid="userColumns"><property name="alias" value="t2"/></include> from some_table t1 cross join some_table t2 </select>
參數(property)也可以在refid或者include進來的sql中使用。示例如下:
<sql id="sometable"> ${prefix}Table </sql> <sql id="someinclude"> from <include refid="${include_target}"/> </sql> <select id="select" resultType="map"> select field1, field2, field3 <include refid="someinclude"> <property name="prefix" value="Some"/> <property name="include_target" value="sometable"/> </include> </select>
4. #{}和${}的區別
- #{}在底層實現上使用?做佔位符來生成PreparedStatement,然後將參數傳入,大多數情況都應使用這個,它更快、更安全。
- ${}將傳入的數據直接顯示生成在sql中。如:order by ${user_id},如果傳入的值是111,那麼解析成sql時的值爲order by 111, 如果傳入的值是id,則解析成的sql爲order by id.
5. 類型別名
什麼地方都少不了這種小技巧,可以讓你少打很多字。
<typeAlias type="com.someapp.model.User" alias="User"/>
6. ResultMap
官方文檔上說這個特性是整個MyBatis中最強大的特性(沒有之一)。其實它做的就是映射結果集。
MyBatis底層使用JDBC,所以查詢出來的結果是ResultSet,如果resultType是一個對象,MyBatis底層就會創建一個resultMap,並根據字段名一一對應上這個對象。如果你有一個查詢,它的結果集非常複雜,可以使用resultMap來做映射。
cache和cach-ref
使用cache標籤在映射文件內(某命名空間內)實現二級緩存,其所有屬性都有缺省值,所以單單一個標籤就可以生效。cach-ref可以在兩個映射文件之間共享緩存
<cache eviction="LRU"//緩存移除策略 flushInterval="60000"//默認不設置,不定時刷新 size="1024" readOnly="false"/>
四、動態SQL
1. if
條件判斷,參數爲test
2. choose (嵌套when,otherwise)
多選一,參數爲test
3. trim (where,set)
- trim標籤可以定製其他標籤,並且去頭去尾;
- where標籤會自動生成where語句,並且可以去除頭部的and或者or;
- set標籤可以自動生成set語句,並且可以去除尾部的逗號。
4. foreach
循環集合輸出,可以循環數組,Iterable對象,或者Map,如果是Map,則index會是key。
<foreach item="item" index="index" collection="list" open="(" separator="," close=")"> #{item} </foreach>
5. bind
聲明一個使用OGNL表達式生成的變量,在sql語句中使用。
--(完)喜歡就轉發 --