1. 程式人生 > 其它 >3-訓練模型

3-訓練模型

Mybatis(二)

三、優化 Mybatis 配置

我們已經在之前的學習中,學會了如何編寫一個簡單的 Mybatis 專案。很顯然這還遠遠沒有正真瞭解 Mybatis。我們從 Mybatis 核心配置檔案 mybatis-config 開始優化我們的專案。

3.1 屬性(properties)

在核心配置檔案中 properties 是一個很重要的標籤。它為 XML 提供外來配置,可以進行動態替換,其中最重要的就在於連線資料庫字串的配置。我們在 resources 資料夾下新建一個 db.properties 檔案:

driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/kimari?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC
username=root
password=123456

在這之後只需要在 XML 中新增一個 properties 標籤,我們就可以簡化我們的 XML 檔案程式碼了:

<properties resource="db.properties"/>

<dataSource type="POOLED">
  <property name="driver" value="${driver}"/>
  <property name="url" value="${url}"/>
  <property name="username" value="${username}"/>
  <property name="password" value="${password}"/>
</dataSource>

如果一個屬性在不只一個地方進行了配置,那麼,MyBatis 將按照下面的順序來載入:

  • 首先讀取在 properties 元素體內指定的屬性。
  • 然後根據 properties 元素中的 resource 屬性讀取類路徑下屬性檔案,或根據 url 屬性指定的路徑讀取屬性檔案,並覆蓋之前讀取過的同名屬性。
  • 最後讀取作為方法引數傳遞的屬性,並覆蓋之前讀取過的同名屬性。

因此,通過方法引數傳遞的屬性具有最高優先順序,resource/url 屬性中指定的配置檔案次之,最低優先順序的則是 properties 元素中指定的屬性。

3.2 類型別名(typeAliases)

類型別名可為 Java 型別設定一個縮寫名字。 它僅用於 XML 配置,意在降低冗餘的全限定類名書寫。例如:

<typeAliases>
  <typeAlias alias="Author" type="domain.blog.Author"/>
  <typeAlias alias="Blog" type="domain.blog.Blog"/>
  <typeAlias alias="Comment" type="domain.blog.Comment"/>
  <typeAlias alias="Post" type="domain.blog.Post"/>
  <typeAlias alias="Section" type="domain.blog.Section"/>
  <typeAlias alias="Tag" type="domain.blog.Tag"/>
</typeAliases>

當然你還可以直接掃描一個包來給這個包裡所有的類設定類型別名:

<typeAliases>
    <package name="com.kimari.pojo"/>
</typeAliases>

下面是一些為常見的 Java 型別內建的類型別名。它們都是不區分大小寫的,注意,為了應對原始型別的命名重複,採取了特殊的命名風格。

別名 對映的型別
_byte byte
_long long
_short short
_int int
_integer int
_double double
_float float
_boolean boolean
string String
byte Byte
long Long
short Short
int Integer
integer Integer
double Double
float Float
boolean Boolean
date Date
decimal BigDecimal
bigdecimal BigDecimal
object Object
map Map
hashmap HashMap
list List
arraylist ArrayList
collection Collection
iterator Iterator

除了用 XML 配置別名,你還可以選擇用 @Alias 註解來設定別名:

@Alias("author")
public class Author {
    ...
}

3.3 設定(settings)

這是 MyBatis 中極為重要的調整設定,它們會改變 MyBatis 的執行時行為。 下面是重要的幾種屬性:

  • cacheEnabled

    全域性性地開啟或關閉所有對映器配置檔案中已配置的任何快取。預設是 true

  • lazyLoadingEnabled

    延遲載入的全域性開關。當開啟時,所有關聯物件都會延遲載入。 特定關聯關係中可通過設定 fetchType 屬性來覆蓋該項的開關狀態。預設是 false

  • mapUnderscoreToCamelCase

    是否開啟駝峰命名自動對映,即從經典資料庫列名 A_COLUMN 對映到經典 Java 屬性名 aColumn。預設是 False

  • logImpl

    指定 MyBatis 所用日誌的具體實現,未指定時將自動查詢。可以選擇 SLF4J | LOG4J | LOG4J2 | JDK_LOGGING | COMMONS_LOGGING | STDOUT_LOGGING | NO_LOGGING

    其中 STDOUT_LOGGING 是標準日誌輸出,它不需要其他依賴,直接就能輸出。

需要注意的是標籤間的順序都是確定的,不能隨意修改。

3.4 環境配置(environments)

MyBatis 可以配置成適應多種環境,這種機制有助於將 SQL 對映應用於多種資料庫之中, 現實情況下有多種理由需要這麼做。例如,開發、測試和生產環境需要有不同的配置;或者想在具有相同 Schema 的多個生產資料庫中使用相同的 SQL 對映。還有許多類似的使用場景。

不過要記住:儘管可以配置多個環境,但每個 SqlSessionFactory 例項只能選擇一種環境。

<environments default="development">
  <environment id="development">
    <transactionManager type="JDBC">
      <property name="..." value="..."/>
    </transactionManager>
    <dataSource type="POOLED">
      <property name="driver" value="${driver}"/>
      <property name="url" value="${url}"/>
      <property name="username" value="${username}"/>
      <property name="password" value="${password}"/>
    </dataSource>
  </environment>
</environments>

事務管理器(transactionManager)

在 MyBatis 中有兩種型別的事務管理器(也就是 type="[JDBC|MANAGED]"):

  • JDBC – 這個配置直接使用了 JDBC 的提交和回滾設施,它依賴從資料來源獲得的連線來管理事務作用域。
  • MANAGED – 這個配置幾乎沒做什麼。它從不提交或回滾一個連線,而是讓容器來管理事務的整個生命週期(比如 JEE 應用伺服器的上下文)。 預設情況下它會關閉連線。然而一些容器並不希望連線被關閉,因此需要將 closeConnection 屬性設定為 false 來阻止預設的關閉行為。

資料來源(dataSource)

dataSource 元素使用標準的 JDBC 資料來源介面來配置 JDBC 連線物件的資源。

有三種內建的資料來源型別(也就是 type="[UNPOOLED|POOLED|JNDI]"):

  • UNPOOLED– 這個資料來源的實現會每次請求時開啟和關閉連線。雖然有點慢,但對那些資料庫連線可用性要求不高的簡單應用程式來說,是一個很好的選擇。 效能表現則依賴於使用的資料庫,對某些資料庫來說,使用連線池並不重要,這個配置就很適合這種情形。

  • POOLED– 這種資料來源的實現利用“池”的概念將 JDBC 連線物件組織起來,避免了建立新的連線例項時所必需的初始化和認證時間。 這種處理方式很流行,能使併發 Web 應用快速響應請求。

  • JNDI – 這個資料來源實現是為了能在如 EJB 或應用伺服器這類容器中使用,容器可以集中或在外部配置資料來源,然後放置一個 JNDI 上下文的資料來源引用。

3.5 對映器(mappers)

既然 MyBatis 的行為已經由上述元素配置完了,我們現在就要來定義 SQL 對映語句了。 但首先,我們需要告訴 MyBatis 到哪裡去找到這些語句。 在自動查詢資源方面,Java 並沒有提供一個很好的解決方案,所以最好的辦法是直接告訴 MyBatis 到哪裡去找對映檔案。 你可以使用相對於類路徑的資源引用,或完全限定資源定位符(包括 file:/// 形式的 URL),或類名和包名等。例如:

<!-- 使用相對於類路徑的資源引用 -->
<mappers>
  <mapper resource="org/mybatis/builder/AuthorMapper.xml"/>
  <mapper resource="org/mybatis/builder/BlogMapper.xml"/>
  <mapper resource="org/mybatis/builder/PostMapper.xml"/>
</mappers>
<!-- 使用對映器介面實現類的完全限定類名 -->
<mappers>
  <mapper class="org.mybatis.builder.AuthorMapper"/>
  <mapper class="org.mybatis.builder.BlogMapper"/>
  <mapper class="org.mybatis.builder.PostMapper"/>
</mappers>
<!-- 將包內的對映器介面實現全部註冊為對映器 -->
<mappers>
  <package name="org.mybatis.builder"/>
</mappers>

注意如果使用類名和包名,介面和他的 Mapper 配置檔案必須同名且必須在同一包下。


四、實現增刪改查

MyBatis 的真正強大在於它的語句對映,這是它的魔力所在。由於它的異常強大,對映器的 XML 檔案就顯得相對簡單。如果拿它跟具有相同功能的 JDBC 程式碼進行對比,你會立即發現省掉了將近 95% 的程式碼。MyBatis 致力於減少使用成本,讓使用者能更專注於 SQL 程式碼。

4.1 select

一個簡單查詢的 select 元素是非常簡單的。比如:

<select id="getUserById" parameterType="_int" resultType="user">
    select *
    from kimari.user
    where id = #{id};
</select>

這個語句名為 getUserById,接收一個 int 型別的引數,並返回一個 User 型別的物件(由於前面已經介紹了別名,我們將省略全限命名)。先介紹幾個比較重要的屬性:

  • id:在名稱空間中唯一的識別符號,可以被用來引用這條語句。
  • parameterType:將會傳入這條語句的引數的類全限定名或別名。這個屬性是可選的,因為 MyBatis 可以通過型別處理器(TypeHandler)推斷出具體傳入語句的引數,預設值為未設定(unset)。
  • resultType:期望從這條語句中返回結果的類全限定名或別名。 注意,如果返回的是集合,那應該設定為集合包含的型別,而不是集合本身的型別。 resultType 和 resultMap 之間只能同時使用一個。
  • resultMap :對外部 resultMap 的命名引用。結果對映是 MyBatis 最強大的特性,如果你對其理解透徹,許多複雜的對映問題都能迎刃而解。 resultType 和 resultMap 之間只能同時使用一個。

如果引數型別是基礎型別,則可以省略不寫。

4.2 insert, update 和 delete

資料變更語句 insert,update 和 delete 的實現非常接近:

<insert id="addUser" parameterType="user">
    insert into kimari.user(id, name, pwd)
    values (#{id}, #{name}, #{pwd});
</insert>
<update id="updateUser" parameterType="user">
    update kimari.user
    set name = #{name},
    pwd = #{pwd}
    where id = #{id};
</update>
<delete id="deleteUser">
    delete
    from kimari.user
    where id = #{id};
</delete>

下面是比較重要的屬性:

  • id:在名稱空間中唯一的識別符號,可以被用來引用這條語句。
  • parameterType:將會傳入這條語句的引數的類全限定名或別名。這個屬性是可選的,因為 MyBatis 可以通過型別處理器(TypeHandler)推斷出具體傳入語句的引數,預設值為未設定(unset)。

請注意:這三個語句並沒有 resultMap 和 resultType 屬性。