MyBatis使用筆記

MyBatisjava

MyBatis做爲一個輕量的SQL映射框架,確實很簡單,可是知識點挺多,實際使用中仍是會有時想不起來某個標籤該怎麼寫,因此整理了這篇文章,以備查詢。因爲MyBatis如此簡單,使得這一篇文章基本把實際使用中常碰到的事情都涵蓋了,包括:sql

  1. MyBatis中的一些概念
  2. MyBatis包含的內容
  3. SQL映射
  4. 動態SQL

1、 MyBatis中的一些概念

MyBatis的架構數據庫

1. MyBatis 是個什麼東西

在使用MyBatis的項目裏,日誌中每每會出現不少拼接SQL語句的log,這其實說明了MyBatis底層仍是使用JDBC來實現的。在JDBC的基礎上,爲了性能考慮,全部的語句都是基於 SqlSession 。顧名思義,維護這個類的實例其實就是維護了一個對於某個數據庫的鏈接的會話,在這個會話裏能夠有緩存啊什麼之類的。數組

2. mapper 接口是怎麼映射成SQL語句的

目前多數開發者仍是會使用XML來進行MyBatis的配置,包括MyBatis的核心配置和SQL映射配置。其實和註解同樣,XML自己只不過是一個元數據的載體,最終起做用的仍是MyBatis的核心類。其中有這樣幾個比較重要的:緩存

  1. SqlSessionFactoryBuilder ,用來建立 SqlSessionFactory 的實例,以後就沒有用了,其生命週期只是在初始化的時候有做用。
  2. SqlSessionFactory ,MyBatis最基礎的類,用來建立會話(即 SqlSession 的實例),其生命週期與整個系統的生命週期相同,在系統運行的任什麼時候候均可以使用它查詢到當前數據庫的配置信息等。
  3. SqlSession ,真正的和數據庫之間的會話,線程不安全,因此其生命週期和使用它的線程相同。
  4. 各類 Mapper ,承載了實際的業務邏輯,其生命週期比較短,由 SqlSession 建立。

3. Spring環境中MyBatis的初始化過程

實際狀況中MyBatis每每是在Spring的環境中使用的,MyBatis自己並不依賴Spring,可是使用Spring能夠極大的提升開發效率,因爲Spring進行了控制反轉,因此其中MyBatis的初始化過程和正常過程稍稍有些不一樣:安全

  1. Spring發現須要建立 SqlSessionFactory 實例,會在classpath下找到MyBatis的核心配置文件,使用它來初始化一個 SqlSessionFactory 實例。固然,這一步徹底可使用代碼來完成,或者使用註解,就更加清晰明瞭。
  2. 每每mapper類也會做爲bean注入到代碼中去的,那麼Spring會使用上一步中的 SqlSessionFactory 實例來建立 SqlSession 的實例。
  3. 而後再使用 SqlSession 嘗試建立各個mapper對象。
  4. 於此同時,MyBatis會掃描classpath下的mapper映射XML文件(此路徑能夠自定義),對於每個mapper接口,它的「類全名」會做爲命名空間,來和映射文件中的mapper標籤進行匹配。
  5. 對於每個映射文件中的一個執行語句標籤(如select、delete),MyBatis會把他們映射到 SqlSession 的方法上,建立mapper接口的一個實現類。
  6. 若是mapper接口和其映射文件一一匹配,則bean建立成功。

2、MyBatis包含的內容

MyBatis自己就是一個簡單的ORM框架,提供了SQL語句到方法、關係型數據表到對象的映射。實際使用中與開發者相關的有兩個東西:架構

  1. MyBatis核心配置 
    緩存、數據源、日誌等關係到MyBatis其自己行爲的一些配置。
  2. mapper接口的映射 
    針對於具體業務邏輯的SQL映射。

3、SQL映射

MyBatis也可使用註解來實現映射,對於簡單的語句,使用註解可能會更加清晰簡單,可是其真正強大的地方仍是XML。app

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標籤能夠包含參數。示例以下:ide

<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. #{} 和 ${} 的區別

  1. #{} 在底層實現上使用 ? 作佔位符來生成PreparedStatement,而後將參數傳入,大多數狀況都應使用這個,它更快、更安全。
  2. ${} 將傳入的數據直接顯示生成在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"/>

4、動態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語句中使用。

相關文章
相關標籤/搜索