1. 程式人生 > >Mybatis學習記錄(三)--Mybatis配置檔案詳解

Mybatis學習記錄(三)--Mybatis配置檔案詳解

關於mybatis的配置檔案,主要有兩個,一個是SqlMapperConfig.xml檔案一個是mapper.xml檔案,分別對這兩個進行深入全面學習.

一.SqlMapperConfig.xml檔案

1.標籤概況

在SqlMapperConfig.xml中主要有以下標籤,其中環境集合environments和spring整合後廢除不用.objectFactory和plugins不經常使用.

  • properties(屬性)
  • settings(全域性配置引數)
  • typeAliases(類型別名)
  • typeHandlers(型別處理器)
  • objectFactory(物件工廠)
  • plugins(外掛)
  • environments(環境集合屬性物件)
  • environment(環境子屬性物件)
  • transactionManager(事務管理)
  • dataSource(資料來源)
  • mappers(對映器)

2.properties

此標籤主要用來引用額外的properties檔案,用來解耦xml和其他特殊的配置引數,比如對於資料庫的配置,可以單獨建立一個db.properties檔案來儲存

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

然後在配置檔案中使用$符號來引用

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
        <!--這裡引入我們的配置檔案-->
    <properties resource="db.properties">
<!--這裡面也可以單獨定義引數--> <property name="" value=""/> </properties> <environments default="development"> <environment id="development"> <transactionManager type="JDBC" /> <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> </configuration>

如果使用這種方式就要了解mybatis對外部引數引用的過程,不然如果命名一樣的引數會出現覆蓋現象
1. 在 properties 元素體內定義的屬性首先被讀取。
2. 然後會讀取properties 元素中resource或 url 載入的屬性,它會覆蓋已讀取的同名屬性。
3. 最後讀取parameterType傳遞的屬性,它會覆蓋已讀取的同名屬性。

因此,通過parameterType傳遞的屬性具有最高優先順序,resource或 url 載入的屬性次之,最低優先順序的是 properties 元素體內定義的屬性。

3.settings

這個是mybatis執行引數的配置,執行引數將會影響mybatis的執行行為。具體可配置的如下表.
這裡寫圖片描述
這裡寫圖片描述
這裡寫圖片描述

4.typeAliases

這個是配置類型別名,一般針對自己寫的pojo類,因為寫全部的類路徑名實在是太長了,用這個定義下會省事很多.

1.預設別名

別名 對映的型別
_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

2.自定義別名

    <typeAliases>
        <!--單個對映配置-->
        <typeAlias type="com.aust.model.User"/>
        <!--對映包內的所有檔案,預設別名為java檔案類名,首字母大小寫均可,但一般小寫-->
        <package name="com.aust.model"/>
    </typeAliases>

5.typeHandlers

型別處理器用於java型別和jdbc型別對映,這個一般mybatis自帶的型別處理器基本上滿足日常需求,不需要單獨定義。具體轉換可以查詢相關文件

6.objectFactory

MyBatis 每次建立結果物件的新例項時,它都會使用一個物件工廠(ObjectFactory)例項來完成。預設的物件工廠需要做的僅僅是例項化目標類,要麼通過預設構造方法,要麼在引數對映存在的時候通過引數構造方法來例項化。預設情況下,我們不需要配置,mybatis會呼叫預設實現的objectFactory。

7.plugin

plugins 是一個可選配置。mybatis中的plugin其實就是個interceptor, 它可以攔截Executor 、ParameterHandler 、ResultSetHandler 、StatementHandler 的部分方法,處理我們自己的邏輯。Executor就是真正執行sql語句的東西, ParameterHandler 是處理我們傳入引數的,還記得前面講TypeHandler的時候提到過,mybatis預設幫我們實現了不少的typeHandler, 當我們不顯示配置typeHandler的時候,mybatis會根據引數型別自動選擇合適的typeHandler執行,其實就是ParameterHandler 在選擇。ResultSetHandler 就是處理返回結果的。

8.mappers

//使用相對於類路徑的資源
<mapper resource="sqlmap/User.xml" />

//使用完全限定路徑
<mapper url="file:///D:\workspace_spingmvc\mybatis_01\config\sqlmap\User.xml" />

//使用mapper介面類路徑,也就是說使用mapper代理開發dao
<mapper class="cn.itcast.mybatis.mapper.UserMapper"/>
//注意:此種方法要求mapper介面名稱和mapper對映檔名稱相同,且放在同一個目錄中。

//註冊指定包下的所有mapper介面,也就是說使用mapper代理開發dao
<package name="cn.itcast.mybatis.mapper"/>
//注意:此種方法要求mapper介面名稱和mapper對映檔名稱相同,且放在同一個目錄中。

二.Mapper.xml檔案

1.輸入型別parameterType

輸入型別可以為簡單型別,pojo類,hashmap等.

1.傳遞簡單型別

mybatis會根據預設別名typeAliases來自動解析型別

//傳入簡單型別int
<select id="findUserById" parameterType="int" resultType="com.aust.model.User">
        SELECT * FROM user WHERE id=#{id}
    </select>

2.傳入hashmap

傳入hashmap的話,則#和$取出的引數都是hashmap中的key

<!--測試使用hashmap傳入引數-->
    <select id="findUser" parameterType="java.util.HashMap" resultType="com.aust.model.User">
        SELECT * FROM user WHERE id=#{id} AND nickname LIKE '%${nickname}%'
    </select>

測試程式碼

//測試取出單個
    @Test
    public void findUserTest(){
        //獲取sqlsession
        SqlSession session = factory.openSession();
        //建立mapper代理
        UserMapper mapper = session.getMapper(UserMapper.class);
        //利用mapper代理查詢
        HashMap<String,Object> map = new HashMap<>();
        map.put("id",1);
        map.put("nickname","牛");
        User u = mapper.findUser(map);
        session.close();
        System.out.println(u);
    }

有問題的就是當hashmap中對應的引數不存在的話,程式並不會報錯,而是查不到結果,這裡可能引發一些異常

3.傳遞pojo物件

這個如果沒使用typeAliases來對映的話就直接傳遞完整類路徑,使用的話就可以傳遞簡單名稱

 <!--根據id查詢出使用者資訊(查詢一條資料)-->
    <select id="findUserById" parameterType="int" resultType="com.aust.model.User">
        SELECT * FROM user WHERE id=#{id}
    </select>

2.輸出型別resultType

和輸入型別用法差不多

1.輸出簡單型別

<!--輸出簡單型別int-->
    <select id="findUserCount" parameterType="java.lang.String" resultType="int">
        SELECT COUNT(*) from user WHERE nickname LIKE '%${value}%'
    </select>

要注意的是輸出簡單型別必須查詢出來的結果集有一條記錄,最終將第一個欄位的值轉換為輸出型別。
使用session的selectOne可查詢單條記錄。

2.輸出pojo型別

mybatis使用session呼叫selectOne查詢單條記錄。和輸入方式一樣的用法

3.pojo列表

mybatis使用session的selectList方法獲取pojo列表。返回資料為List

4.輸出hashmap

輸出pojo物件可以改用hashmap輸出型別,將輸出的欄位名稱作為map的key,value為欄位值。

3.輸出型別resultMap

resultType可以指定pojo將查詢結果對映為pojo,但需要pojo的屬性名和sql查詢的列名一致方可對映成功。如果sql查詢欄位名和pojo的屬性名不一致,可以通過resultMap將欄位名和屬性名作一個對應關係,resultMap實質上還需要將查詢結果對映到pojo物件中。resultMap可以實現將查詢結果對映為複雜型別的pojo,比如在查詢結果對映物件中包括pojo和list實現一對一查詢和一對多查詢。

1.定義resultMap

    <!--id:此resultMap的唯一表示
        type:對映的型別
    -->
    <resultMap id="userMap" type="com.aust.model.User">
        <!--id:該查詢記錄的唯一標示,也就是主鍵
            result:普通列對映標示
            column:要對映的查詢結果sql列
            property;要對映為pojo的那個屬性名
        -->
        <id column="id_" property="id"/>
        <result column="username_" property="username"/>
    </resultMap>

2.使用resultMap

 <!--根據id查詢出使用者資訊(查詢一條資料)-->
    <select id="findUserById" parameterType="int" resultMap="userMap">
        SELECT id id_,username username_,password,nickname,status FROM user WHERE id=#{id}
    </select>

從程式碼可以看出,我給id和username分別起了別名id_,username_,然後返回型別為之前定義的userMap,這樣的話查詢結果自動會把id_對映為User類的id,username_對映為User類的username.
列表內容

下一篇關聯查詢會介紹更多

3.動態sql

通過mybatis提供的各種標籤方法實現動態拼接sql。

1.if標籤

<!-- 傳遞pojo綜合查詢使用者資訊 -->
    <select id="findUserList" parameterType="user" resultType="user">
        select * from user 
        where 1=1 
        <if test="id!=null and id!=''">
        and id=#{id}
        </if>
        <if test="username!=null and username!=''">
        and username like '%${username}%'
        </if>
    </select>

2.where標籤

where主要解決了上面單純用if標籤還要寫where 1=1這樣的多餘條件的情況.

<select id="findUserList" parameterType="user" resultType="user">
        select * from user 
        <where>
        <if test="id!=null and id!=''">
        and id=#{id}
        </if>
        <if test="username!=null and username!=''">
        and username like '%${username}%'
        </if>
        </where>
    </select>

3.foreach標籤

foreach遍歷集合和陣列進行sql語句拼接,看下面例子

SELECT * FROM USERS WHERE username LIKE '%張%' AND id IN (10,89,16)

有上面這樣的sql,那麼用foreach假設傳了陣列a{10,89,16}或者集合a{10,89,16}

<foreach collection="a" open=" and id in(" close=")" item="id" separator="," >
                #{id}
</foreach>
  • collection:傳入的陣列或者集合名稱
  • open:遍歷開始前加入的字首,這裡是AND id IN (
  • close:遍歷結束加入的字尾,這裡是)
  • item:要遍歷的專案,為pojo的時候,取出引數就要用#{pojo.屬性名}
  • separator:每個專案之間的分隔符

如果傳遞的為陣列的話,裡面還有有個index屬性,來表示陣列的下標

4.sql片段

Sql中可將重複的sql提取出來,使用時用include引用即可,最終達到sql重用的目的
sql片段用sql標籤包裹起來

<sql id="query_user_where">
    <if test="id!=null and id!=''">
        and id=#{id}
    </if>
    <if test="username!=null and username!=''">
        and username like '%${username}%'
    </if>
</sql>

引用方式

如果引用的為其他mapper.xml的片段,則需要使用 namespace.sql片段名

專案示例: