Mybatis 學習筆記(一)——配置檔案SqlMapConfig.xml和對映檔案Mapper.xml

lytao123發表於2018-10-13

一、SqlMapConfig.xml

(一)properties(屬性)
  將資料庫連線引數單獨配置在db.properties中,只需要在SqlMapConfig.xml中載入db.properties的屬性值。在SqlMapConfig.xml中就不需要對資料庫連線引數硬編碼。
db.properties配置檔案內容

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis
jdbc.username=root
jdbc.password=123456

SqlMapConfig.xml中配置

<!-- 載入屬性檔案 -->
<properties resource="config/db.properties"></properties>

SqlMapConfig.xml中通過${引數名}引用db.properties檔案中配置的引數

<property name="driver" value="${jdbc.driver}" />

(二)settings(全域性配置引數)
  主要的配置引數有如下這些,作用於整個 Mybatis :
Setting配置參數列
在SqlMapConfig.xml中配置

<!-- 全域性配置引數 -->
<settings>
	<setting name="cacheEnabled" value="true"/>
</settings>

(三)typeAliases(型別別名)
  在 Mapper.xml 中需要定義很多的 Statement,如果在指定型別時輸入型別全路徑,不方便進行開發,可以針對 parameterType 或 resultType 指定的型別定義一些別名,在 SqlMapConfig.xml 中通過別名定義,方便開發。
其中 Mybatis 提供了一些預設別名的定義:
Mybatis 預設別名定義表
當然我們還可以自定義別名單個別名定義和批量定義

<!-- 定義別名 -->
<typeAliases>
	<!-- 針對單個別名定義 -->
	<typeAlias type="com.po.User" alias="user"/>
</typeAliases>

引用單個別名的定義

<insert id="insertUser" parameterType="user">
	<selectKey keyProperty="id" order="AFTER" resultType="int">
		SELECT LAST_INSERT_ID()
	</selectKey>
	INSERT INTO USER(USERNAME,SEX,BIRTHDAY,ADDRESS) VALUES(#{username},#{sex},#{birthday},#{address})
</insert>
<!-- 定義別名 -->
<typeAliases>
	<!-- 針對批量別名定義,別名就是類名(首字母大小寫都可以) -->
	<package name="com.po"/>
</typeAliases>

  批量定義的別名的引用和單個定義的是一樣的,建議使用批量別名定義各pojo的別名,提高開發效率。

(四)typeHandlers(型別處理器)
  Mybatis 中通過 typeHandlers 完成 jdbc 型別和 java 型別的轉換。通常情況下,Mybatis 提供的型別處理器滿足日常需要,不需要自定義,如果需要定義,如下:

<!-- 型別處理器 ,不需要自定義-->
<typeHandlers>
	<typeHandler handler="" javaType="" jdbcType=""/>
</typeHandlers>

Mybatis 支援型別處理器:
Mybatis 支援型別處理器表

(五)objectFactory(物件工廠)
  MyBatis 每次建立結果物件的新例項時,它都會使用一個物件工廠(ObjectFactory)例項來完成。 預設的物件工廠需要做的僅僅是例項化目標類,要麼通過預設構造方法,要麼在引數對映存在的時候通過引數構造方法來例項化。 如果想覆蓋物件工廠的預設行為,則可以通過建立自己的物件工廠來實現。
6. plugins(外掛)
  簡單理解為攔截器,既然是攔截器說白了一般都是動態代理來實現對目標方法的攔截,在前後做一些操作。 在mybatis將這種東西,稱之為plugin,配置在SqlMapConfig.xml 配置檔案中,通過 plugins 標籤配置。在Mybatis中,可以被攔截的目標主要是:
1. StatementHandler(SQL語句處理器);
2. ParameterHandler(引數處理器 );
3. ResultSetHandler(結果集處理器 );
4. Executor(執行器 );

(七) environments(環境集合屬性物件)
  MyBatis 可以配置多種環境。但每個資料庫對應一個 SqlSessionFactory。

  1. environment(環境子屬性物件)
<!-- 和Spring整合後environments配置將廢除 -->
<environments default="development">
	<environment id="development">
	</environment>
</environments>
  1. transactionManager(事務管理)
<!-- 使用JDBC事務管理,事務控制由mybatis管理 -->
<transactionManager type="JDBC" />
  1. dataSource(資料來源)
<!-- 資料庫連線池,由mybatis管理 -->
<dataSource type="POOLED">
	<property name="driver" value="${jdbc.driver}" />
	<property name="url" value="${jdbc.url}" />
	<property name="username" value="${jdbc.username}" />
	<property name="password" value="${jdbc.password}" />
</dataSource>

將這三個合一塊就是:

<!-- 和Spring整合後environments配置將廢除 -->
<environments default="development">
	<environment id="development">
		<!-- 使用JDBC事務管理,事務控制由mybatis管理 -->
		<transactionManager type="JDBC" />
		<!-- 資料庫連線池,由mybatis管理 -->
		<dataSource type="POOLED">
			<property name="driver" value="${jdbc.driver}" />
			<property name="url" value="${jdbc.url}" />
			<property name="username" value="${jdbc.username}" />
			<property name="password" value="${jdbc.password}" />
		</dataSource>
	</environment>
</environments>

(八)mappers(對映器)
  Mappers 標籤是用來載入對映檔案的,可通過下列四種方式載入對映檔案
(1)通過resource載入單個mapper

<!-- 通過resource載入 -->
<mapper resource="config/sqlmap/User.xml" />

(2)通過使用完全限定路徑

<!-- 通過url載入 -->
<mapper url="config/sqlmap/User.xml" />

(3)通過mapper介面載入單個mapper

<!-- 通過mapper介面載入,但需要將介面名和對映檔名儲存一致,且在同一目錄 -->
<mapper class="com.dao.UserDao"/>

(4)批量載入mapper(推薦使用)

<!-- 批量載入 -->
<package name="com.po"/>

二、Mapper.xml

  對映檔案 Mapper.xml 是 Mybatis 的核心,對映檔案中需要定義運算元據庫的SQL語句,每個SQL就是一個statement。

1. insert、update、delete

  三個的屬性差不多,意思也一樣。下面以insert為例。在實際使用過程中並不需要都進行配置,可根據自己的需要刪除部分配置項。

<insert
      <!-- 1. id (必須配置)
        id是名稱空間中的唯一識別符號,可被用來代表這條語句。 
        一個名稱空間(namespace) 對應一個dao介面, 
        這個id也應該對應dao裡面的某個方法(相當於方法的實現),因此id 應該與方法名一致 -->
      
      id="addUser"
      
      <!-- 2. parameterType (可選配置, 預設為mybatis自動選擇處理)
        將要傳入語句的引數的完全限定類名或別名, 如果不配置,mybatis會通過ParameterHandler 根據引數型別預設選擇合適的typeHandler進行處理
        parameterType 主要指定引數型別,可以是int, short, long, string等型別,也可以是複雜型別(如物件) -->
      
      parameterType="user"
      
      <!-- 3. flushCache (可選配置,預設配置為true)
        將其設定為 true,任何時候只要語句被呼叫,都會導致本地快取和二級快取都會被清空,預設值:true(對應插入、更新和刪除語句) -->
      
      flushCache="true"
      
      <!-- 4. statementType (可選配置,預設配置為PREPARED)
        STATEMENT,PREPARED 或 CALLABLE 的一個。這會讓 MyBatis 分別使用 Statement,PreparedStatement 或 CallableStatement,預設值:PREPARED。 -->
      
      statementType="PREPARED"
      
      <!-- 5. keyProperty (可選配置, 預設為unset)
        (僅對 insert 和 update 有用)唯一標記一個屬性,MyBatis 會通過 getGeneratedKeys 的返回值或者通過 insert 語句的 selectKey 子元素設定它的鍵值,預設:unset。如果希望得到多個生成的列,也可以是逗號分隔的屬性名稱列表。 -->
      
      keyProperty=""
      
      <!-- 6. keyColumn     (可選配置)
        (僅對 insert 和 update 有用)通過生成的鍵值設定表中的列名,這個設定僅在某些資料庫(像 PostgreSQL)是必須的,當主鍵列不是表中的第一列的時候需要設定。如果希望得到多個生成的列,也可以是逗號分隔的屬性名稱列表。 -->
      
      keyColumn=""
      
      <!-- 7. useGeneratedKeys (可選配置, 預設為false)
        (僅對 insert 和 update 有用)這會令 MyBatis 使用 JDBC 的 getGeneratedKeys 方法來取出由資料庫內部生成的主鍵(比如:像 MySQL 和 SQL Server 這樣的關聯式資料庫管理系統的自動遞增欄位),預設值:false。  -->
      
      useGeneratedKeys="false"
     
      <!-- 8. timeout  (可選配置, 預設為unset, 依賴驅動)
        這個設定是在丟擲異常之前,驅動程式等待資料庫返回請求結果的秒數。預設值為 unset(依賴驅動)。 -->
      timeout="20" >
	   <!-- 
		   將插入的主鍵返回到user物件中(這裡用的是自增主鍵MySQL資料庫) 
		   SELECT LAST_INSERT_ID():得到將insert進去的記錄的主鍵值,只適用與自增主鍵
		   keyProperty:將查詢到的主鍵設定到parameterType指定的物件的哪個屬性
		   order:SQL語句執行的順序,BEFORE或AFTER
	   -->
	   <selectKey keyProperty="id" order="AFTER" resultType="int">
		   SELECT LAST_INSERT_ID()
	   </selectKey>
	   INSERT INTO USER(USERNAME,SEX,BIRTHDAY,ADDRESS) VALUES(#{username},#{sex},#{birthday},#{address})
</insert>

在insert時,如果資料庫的主鍵不能自增,可以使用下面的配置來實現相同的功能:

<insert id="insertUser" parameterType="com.dy.entity.User">
         <!-- 可根據其id生成策略,先獲取id,在進行插入 -->
       <selectKey keyProperty="id" order="BEFORE" resultType="int">
             select SEQ_USER_ID.nextval as id from dual
       </selectKey>
          INSERT INTO USER(ID,USERNAME,SEX,BIRTHDAY,ADDRESS) VALUES(#{id},#{username},#{sex},#{birthday},#{address})
</insert>

2. select

  在實際使用過程中並不需要都進行配置,可根據自己的需要刪除部分配置項。

<select
	<!--  1. id (必須配置)
	       id是名稱空間中的唯一識別符號,可被用來代表這條語句。 
	       一個名稱空間(namespace) 對應一個dao介面, 
	       這個id也應該對應dao裡面的某個方法(相當於方法的實現),因此id 應該與方法名一致  -->
    id="findUserById"
    
    <!-- 2. parameterType (可選配置, 預設為mybatis自動選擇處理)
       將要傳入語句的引數的完全限定類名或別名, 如果不配置,mybatis會通過ParameterHandler 根據引數型別預設選擇合適的typeHandler進行處理
       parameterType 主要指定引數型別,可以是int, short, long, string等型別,也可以是複雜型別(如物件) -->
    parameterType="int"
    
    <!-- 3. resultType (resultType 與 resultMap 二選一配置)
        resultType用以指定返回型別,指定的型別可以是基本型別,可以是java容器,也可以是javabean -->
    resultType="user"
    
    <!-- 4. resultMap (resultType 與 resultMap 二選一配置)
        resultMap用於引用我們通過 resultMap標籤定義的對映型別,這也是mybatis元件高階複雜對映的關鍵 -->
    resultMap="userResultMap"
    
    <!-- 5. flushCache (可選配置)
        將其設定為 true,任何時候只要語句被呼叫,都會導致本地快取和二級快取都會被清空,預設值:false -->
    flushCache="false"
    
    <!-- 6. useCache (可選配置)
        將其設定為 true,將會導致本條語句的結果被二級快取,預設值:對 select 元素為 true -->
    useCache="true"
    
    <!-- 7. timeout (可選配置) 
        這個設定是在丟擲異常之前,驅動程式等待資料庫返回請求結果的秒數。預設值為 unset(依賴驅動)-->
    timeout="10000"
    
    <!-- 8. fetchSize (可選配置) 
        這是嘗試影響驅動程式每次批量返回的結果行數和這個設定值相等。預設值為 unset(依賴驅動)-->
    fetchSize="256"
    
    <!-- 9. statementType (可選配置) 
        STATEMENT,PREPARED 或 CALLABLE 的一個。這會讓 MyBatis 分別使用 Statement,PreparedStatement 或 CallableStatement,預設值:PREPARED-->
    statementType="PREPARED"
    
    <!-- 10. resultSetType (可選配置) 
        FORWARD_ONLY,SCROLL_SENSITIVE 或 SCROLL_INSENSITIVE 中的一個,預設值為 unset (依賴驅動)-->
    resultSetType="FORWARD_ONLY">
	SELECT * FROM USER WHERE ID = #{id}
</select>

3. resultType 和 resultMap

  在實際使用過程中並不需要都進行配置,可根據自己的需要刪除部分配置項。
  使用resultType進行輸出對映,只有查詢出來的列名和pojo中的屬性名一致,該列才可以對映成功。
  如果查詢出來的列名和pojo中的屬性名全部不一致,沒有建立pojo物件。
  只要查詢出來的列名和pojo中的屬性有一個一致,就會建立pojo物件。

<select id="findUserByName" parameterType="java.lang.String"
	resultType="user">
	SELECT * FROM USER WHERE USERNAME LIKE '%${value}%'
</select>

  如果查詢出來的列名和pojo的屬性名不一致,通過定義一個resultMap對列名和pojo屬性名之間作一個對映關係。步驟:
1、定義resultMap
2、使用resultMap作為statement的輸出對映型別

<!-- 定義查詢訂單及關聯使用者資訊結果的resultMap -->
<resultMap type="com.po.Orders" id="OrdersResultMap">
	<!-- 配置對映的訂單資訊 -->
	<id column="id" property="id"/>
	<result column="user_id" property="userId"/>
	<result column="number" property="number"/>
	<result column="createtime" property="createtime"/>
	<result column="note" property="note"/>
</resultMap>

<!-- 使用resultMap  -->
<select id="findOrdersUserResultMap" resultMap="OrdersResultMap">
	SELECT
		ORDERS.*
	FROM
		ORDERS,
		USER u
	WHERE
		ORDERS.user_id = u.ID
</select>

  使用resultType進行輸出對映,只有查詢出來的列名和pojo中的屬性名一致,該列才可以對映成功。如果查詢出來的列名和pojo的屬性名不一致,通過定義一個resultMap對列名和pojo屬性名之間作一個對映關係。

4. resultType 和 resultMap 的區別

  resultType:實現簡單,查詢出來的列名不包含在POJO中需增加列名對應的屬性才能完成對映。如果沒有查詢結果的特殊要求建議使用resultType。
  resultMap:需單獨定義resultMap,實現麻煩,但如果對查詢結果有特殊的要求,使用resultMap可以完成將關聯查詢對映pojo的屬性中。
  resultMap可實現延遲載入,而 resultType無法實現。

[1] Mybatis中Mapper對映檔案詳解 https://blog.csdn.net/majinggogogo/article/details/72123185

相關文章