1. 程式人生 > >Mybatis 坑路2 -> MyBatis 配置詳解

Mybatis 坑路2 -> MyBatis 配置詳解

####使用 XML 配置 MyBatis

  Mybatis 最關鍵的組成部分是 SqlSessionFactory,我們可以從中獲取 SqlSession,並執行對映的 SQL 語句。
  SqlSessionFactory 物件可以通過基於 XML 的配置資訊或者 Java API 建立。
  構建 SqlSessionFactory 最常見的方式是基於 XML 配置的構造方式。下面的 mybatis-config.xml 展示了一個典型的 MyBatis 配置檔案的樣子:

配置檔案示例

<configuration>
	<typeAliases>
		<typeAlias alias="Student" type="xx.mybatis3.domain.Student" />
		<package name="xx.mybatis3.domain" />
	</typeAliases>
	<typeHandlers>
		<typeHandler handler="xx.mybatis3.typehandlers.PhoneTypeHandler" />
		<package name="xx.mybatis3.typehandlers" />
	</typeHandlers>
	<environments default="development">
		<environment id="development">
			<transacionManager type="JDBC" />
			<dataSource type="POOLED">
				<property name="driver" value="${jdbc.driverClassName}" />
				<property name="url" value="${jdbc.url}" />
				<property name="username" value="${jdbc.username}" />
				<property name="password" value="${jdbc.password}" />
			</dataSource>
		</environment>
		<environment id="production">
			<transactionManager type="MANAGED" />
			<dataSource type="JNDI">
				<property name="data_source" value="java:comp/jdbc/MyBatisDemoDS" />
			</dataSource>
		</environment>
	</environments>
	<mappers>
		<mapper resource="xx/mybatis3/mappers/StudentMapper.xml" />
		<mapper url="file:///E:/xx/mapper/StudentMapper.xml" />
		<mapper class="xx.mybatis3.mapper.StudentMapper" />
	</mappers>
</configuration>

  Mybatis 支援配置多個 dataSource 環境,可以將應用部署到不同的環境上,如 DEV(開發環境),TEST(測試環境),QA(質量評估環境),UAT(使用者驗收環境),PRODUCTION(生產環境),可以通過將預設 environment 值設定成想要的 environment id值。
  在上述的配置中,預設的環境 environment 被設定成 development。當需要將程式部署到生產伺服器上時,不需要修改什麼配置,只需要將 environments default 的值設定成生產環境的 environment id 屬性的值即可。

將 <environments default="development">修改成<environments default="production">

  有時候,我們可能需要在相同的應用下使用多個數據庫。比如我們可能有 SHOPPING-CART 資料庫來儲存所有的訂單明細:使用 REPORTS 資料庫儲存訂單明細的合計,用作報告。
  如果你的應用需要連線多個數據庫,你需要將每個資料庫配置成獨立的環境,並且為每一個數據庫建立一個 SqlSessionFactory。

environment 配置

<environments default="shoppingcart">
	<environment id="shoppingcart">
		<transactionManager type="MANAGED" />
		<dataSource type="JNDI">
			<property name="data_source" value="java:comp/jdbc/ShoppingcartDS" />
		</dataSource>
	</environment>
	<environment id="reports">
		<transationManager type="MANAGED" />
		<dataSource type="JNDI">
			<property name="data_source" value="java:comp/jdbc/ReportsDS" />
		</dataSource>
	</environment>
</environments>

接下來為每個環境建立一個 SqlSessionFactory

inputStream = Resources.getResourceAsStream("mybatis-config.xml");
defaultSqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
cartSqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream,"shoppingcart");
reportSqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream,"reports");

  建立 SqlSessionFactory 時,如果沒有明確指定環境 environment id,則會使用預設的環境 environment 來建立。在上述的原始碼中,預設的 SqlSessionFactory 便是使用 shoppingcart 環境設定建立的。
  對於每個環境 environment,我們需要配置 dataSource 和 transactionManager 元素

dataSource 配置

dataSource 元素被用來配置資料庫連線屬性。

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

  dataSource 的型別可以配置成其內建型別之一,如 UNPOOLED、POOLED、JNDI。
  如果將型別設定成 UNPOOLED,MyBatis 會為每一個數據庫操作建立一個新的連線操作完成後關閉它。該方式適用於只有小規模數量併發使用者的簡單應用程式上。
  如果將屬性設定成 POOLED,MyBatis 會建立一個數據庫連線池,連線池中的一個連線將會被用作資料庫操作。一旦資料庫操作完成,MyBatis 會將此連線返回給連線池。在開發或測試環境中,經常使用此種方式。
  如果將型別設定成 JNDI,MyBatis 從在應用伺服器向配置好的 JNDI 資料來源 dataSource 獲取資料庫連線。在生產環境中,優先考慮這種方式。

transactionManager 配置

  transactionManager 用來配置事務管理器,MyBatis 支援兩種型別的事務管理器:JDBC 和 MANAGED。
  JDBC 事務管理器被用作當應用陳旭負責管理資料庫連線的生命週期(提交、回退等等)的時候。當 TransactionManager 屬性設定成 JDBC,MyBatis 內部將使用 JdbcTransactionFactory 類建立 TransactionManager。

   例如,部署到 Apache Tomcat 的應用程式,需要應用程式自己管理事務。

  MANAGED 事務管理器是當由應用伺服器負責管理資料庫連線生命週期的時候使用。當你將 TransactionManager 屬性設定成 MANAGED 時,MyBatis 內部使用 ManagedTransactionFactory 類建立事務管理器 TransactionManager。

  例如,當一個 JavaEE 的應用程式部署在類似 JBoss、WebLogin、GlassFish 應用伺服器上時,它們會使用 EJB 進行應用伺服器的事務管理能力。在這些管理環境中,你可以使 MANAGED 事務管理器。
  Managed 是託管的意思,即是應用本身不去管理事務,而是把事務管理交給應用所在的伺服器進行管理。

properties 配置

  properties 屬性配置元素,可以將配置值具體化到一個屬性檔案中,並且使用屬性檔案的 key 名作為佔位符。在上述的配置中,我們將資料庫連線屬性具體化到 application.properties 檔案中,並且為 driver、url 等屬性使用了佔位符。

  • 1、在 application.properties 檔案中配置資料庫連線引數,如下所示:
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis3
jdbc.username=root
jdbc.password=root
  • 2、在 mybatis-config.xml 檔案中,使屬性為 application.properties 檔案中定義的佔位符
<properties resource="application.properties">
	<property name="jdbc.username" value="admin" />
	<property name="jdbc.password" value="123456" />
</properties>
<dataSource type="POOLED">
	<property name="driver" value="${jdbc.driverClassName}" />
	<property name="url" value="${jdbc.url}" />
	<property name="username" value="${jdbc.username}" />
	<property name="password" value="${jdbc.password}" />
</dataSource>

  可以在<properties>元素中配置預設引數的值。如果在<properties>中定義的元素和屬性檔案定義元素的 key 值相同,它們會被屬性未鑑中定義的值覆蓋。

<properties resource="application.properties">
	<property name="jdbc.username" value="admin" />
	<property name="jdbc.password" value="123456" />
</properties>

  如果 application.properties 檔案包含值 jdbc.username 和 jdbc.password,則上述定義的 username 和 password 的值 admin 和 123456 將會被 application.properties 中定義的對應的 jdbc.username 和 jdbc.password 值覆蓋。
  typeAliases 類型別名配置,在 SQLMapper 配置檔案中,對於 resultType 和 parameterType 屬性值,需要使用 JavaBean 的完全限定名:

<select id="findStudentById" parameterType="int" resultType="xx.mybatis3.domain.Student">
	SELECT STUD_ID AS ID,NAME,EMAIL,DOB FROM STUDENTS WHERE STUD_ID=#{id}
</select>
<update id="updateStudent" parameterType="xx.mybatis3.domain.Student">
	UPDATE STUDENTS SET NAME=#{name},EMAIL=#{email},DOB=#{dob} WHERE STUD_ID=#{id}
</update>

  我們可以為完全限定名取一個別名(alias),然後其所需要使用完全限定名的地方使用別名,而不是匯出使用完全限定名。

<typeAliases>
	<typeAlias alias="Student" type="xx.mybatis3.domain.Student" />
	<typeAlias alias="Teacher" type="xx.mybatis3.domain.Teacher" />
	<package name="xx.mybatis3.domain" />
</typeAliases>

  然後在 SQL Mapper 對映檔案中,如下使用 Student 的別名:

<select id="findStudentById" parameterType="int" resultType="Student">
	SELECT STUD_ID AS ID,NAME,EMAIL,DOB FROM STUDENTS WHERE STUD_ID = #{id}
</select>

  不需要為每一個 JavaBean 單獨定義別名,可以為提供需要取別名的 JavaBean 所在的包(package),MyBatis 會自動掃描包內定義的 JavaBeans,然後分別為 JavaBean 註冊一個小寫字幕開頭的非完全限定的類名形式的別名。如下所示,提供一個需要為 JavaBeans 起別名的包名:

<typeAliases>
	<package name="xx.mybatis3.domain" />
</typeAliases>

  如果 Student.java 定義在 xx.mybatis3.domain 包中,則 xx.mybatis3.domain.Student 的別名會被註冊為 student。
  還有另外一種方式為 JavaBeans 起別名,使用註解 @Alias

@Alias("StudentAlias")
public class Student{
}

  @Alias 註解將會覆蓋配置檔案中的<typeAliases>定義。

typeHandlers 配置

  typeHandlers 用來配置型別處理器,當 MyBatis 將一個 Java 物件作為輸入引數執行 INSERT 語句操作時,它會建立一個 PreparedStatement 物件,並且使用 setXXX()方式對佔位符設定相應的引數值。這裡 XXX 可以是 Integer、String、Date 等 Java 物件屬性型別的任意一個。
  當 MyBatis 是怎麼知道對於 Integer型別屬性使用 setInt() 和 String 型別屬性使用 setString()方法呢?其實 MyBatis 是通過使用型別處理器(type handlers)來決定這麼做的。

settings 配置

  settings 配置用來設定全域性引數,為滿足應用特定的需求 MyBatis 預設的全域性引數設定可以被 settings 設定覆蓋掉。

<settings>
	<setting name="cacheEnabled" value="true" />
	<setting name="lazyLoadingEnabled" value="true" />
	<setting name="multipleResultSetsEnabled" value="true" />
	<setting name="useColumnLabel" value="true" />
	<setting name="useGenerateKeys" value="false" />
	<setting name="autoMappingBehavior" value="PARTIAL" />
	<setting name="defaultExecutorType" value="SIMPLE" />
	<setting name="defaultStatementTimeout" value="25000" />
	<setting name="safeRowBoundsEnabled" value="false" />
	<setting name="mapUnderscoreToCamelCase" value="false" />
	<setting name="localCacheScope" value="SESSION" />
	<setting name="jdbcTypeForNull" value="OTHER" />
	<setting name="lazyLoadTriggerMethods" value="equals.clone.hashCode.toString" />
</settings>

mappers 配置

  Mapper XML 檔案中包含的 SQL 對映語句將會被應用通過使用其 statement id 來執行,需要在 mybatis-config.xml 檔案中配置 SQL Mapper 檔案的位置。

<mappers>
	<mapper resource="xx/mybatis3/mappers/StudentMapper.xml" />
	<mapper url="file:///E:/"xx/mappers/StudentMapper.xml" />
	<mapper class="xx.mybatis3.mappers.StudentMapper" />
</mappers>
  • resource 屬性用來指定在 classpath 中的 mapper 檔案
  • url 屬性用來通過完全檔案系統路徑或者 web URL 地址來指定 mapper 檔案
  • class 屬性用來指向一個 mapper 介面
  • package 屬性用來指向可以找到 Mapper 介面的包名