1. 程式人生 > >關於Mybatis框架的個人總結

關於Mybatis框架的個人總結

一:什麼是Mybatis?
剛學會jdbc的時候,對資料庫進行增刪改差,都要事先先寫一個連線工具類,用來載入驅動、獲取資料庫連線還有用完關閉連線這些通用操作,就像下面這張圖

這裡寫圖片描述

然後操作dao層,增刪改差方法每個還要封裝一遍,程式碼重複枯燥,很沒意思。
所以為了解決這個問題,由ibatis改進的Mybatis出現了,他讓我這樣的瓜皮程式設計師能夠不因為太多繁雜重複的程式碼粗心犯低階錯誤,直接把jdbc對資料庫操作的過程封裝起來,只需要寫一寫SQL語句,配置一下連線資訊,萬事大吉。

下面是mybatis的內部架構:
這裡寫圖片描述

1.最頂上的SqlMapConfig.xml
就是前面說的要配置連線資訊之類的檔案,我們把資料庫連線等資訊放在這裡,還有就是mybatis的執行環境之類的

2.SqlSessionFactory
意思是會話工廠(這裡可以小小的涉及一下設計模式的工廠模式),沒錯,工廠工廠,就是生產東西的,這裡也就是生產了會話SqlSession買這個SqlSession拿來做什麼呢,接下來看。(順便說一下,這個工廠是重量級的,用單例模式建立)

3.SqlSession和Executor
我印象裡記得只有SqlSession,其實SqlSession只是打開了資料庫,真正與資料庫互動的也就是真正操作資料庫的是Executor
mybatis底層自定義了Executor執行器介面操作資料庫,Executor介面有兩個實現,一個是基本執行器、一個是快取執行器

4.Mapped Statement
Mapped Statement也是mybatis一個底層封裝物件,它包裝了mybatis配置資訊及sql對映資訊等。mapper.xml檔案中一個sql對應一Mapped Statement物件,sql的id即是Mapped statement的id

二:常見配置

1.自定義別名

在SqlMapConfig.xml中配置:
<typeAliases>
    <!-- 單個別名定義 -->
    <typeAlias alias="user" type="com.mybatis.po.User"/>
    <!-- 批量別名定義,掃描整個包下的類,別名為類名(首字母大寫或小寫都可以) -->
<package name="com.mybatis.po"/> <package name="其它包"/> </typeAliases>

2.寫SQL語句中,#{}與${}的區別

使用佔位符#{}可以有效防止sql注入,在使用時不需要關心引數值的型別,mybatis會自動進行java型別和jdbc型別的轉換。#{}可以接收簡單型別值或pojo屬性值,如果parameterType傳輸單個簡單型別值,#{}括號中可以是value或其它名稱。

和#{}不同,通過${}可以將parameterType 傳入的內容拼接在sql中且不進行jdbc型別轉換, ${}可以接收簡單型別值或pojo屬性值,如parameterType傳輸單個簡單型別值,${}括號中只能是value。使用${}不能防止sql注入,但是有時用${}會非常方便,如下的例子:

<!-- 根據名稱模糊查詢使用者資訊 -->
    <select id="selectUserByName" parameterType="string" resultType="user">
       select * from user where username like '%${value}%'
    </select>

如果本例子使用#{}則傳入的字串中必須有%號,而%是人為拼接在引數中,顯然有點麻煩,如果採用${}在sql中拼接為%的方式則在呼叫mapper介面傳遞引數就方便很多。

4.延遲載入(懶載入)

需要查詢關聯資訊時,使用mybatis延遲載入特性可有效的減少資料庫壓力,首次查詢只查詢主要資訊,關聯資訊等使用者獲取時再載入。

作用:
當需要查詢關聯資訊時再去資料庫查詢,預設不去關聯查詢,提高資料庫效能。
只有使用resultMap支援延遲載入設定。

場合:
當只有部分記錄需要關聯查詢其它資訊時,此時可按需延遲載入,需要關聯查詢時再向資料庫發出sql,以提高資料庫效能。
當全部需要關聯查詢資訊時,此時不用延遲載入,直接將關聯查詢資訊全部返回即可,可使用resultType或resultMap完成對映。

那麼,不使用mybatis提供的延遲載入功能是否可以實現延遲載入?

實現方法:
針對訂單和使用者兩個表定義兩個mapper方法。
1、訂單查詢mapper方法
2、根據使用者id查詢使用者資訊mapper方法
預設使用訂單查詢mapper方法只查詢訂單資訊。
當需要關聯查詢使用者資訊時再呼叫根據使用者id查詢使用者資訊mapper方法查詢使用者資訊。

所以,感覺平時用到延遲載入的地方不多,瞭解知道這個知識應該就好吧

5.查詢快取

mybatis框架、一二級快取

這裡寫圖片描述

從這個圖也可以看出來
Mybatis一級快取的作用域是同一個SqlSession,在同一個sqlSession中兩次執行相同的sql語句,第一次執行完畢會將資料庫中查詢的資料寫到快取(記憶體),第二次會從快取中獲取資料將不再從資料庫查詢,從而提高查詢效率。當一個sqlSession結束後該sqlSession中的一級快取也就不存在了。Mybatis預設開啟一級快取。

一級快取區域是根據SqlSession為單位劃分的。
每次查詢會先從快取區域找,如果找不到從資料庫查詢,查詢到資料將資料寫入快取。
Mybatis內部儲存快取使用一個HashMap,key為hashCode+sqlId+Sql語句。value為從查詢出來對映生成的java物件
sqlSession執行insert、update、delete等操作commit提交後會清空快取區域。

Mybatis二級快取是多個SqlSession共享的,其作用域是mapper的同一個namespace,不同的sqlSession兩次執行相同namespace下的sql語句且向sql中傳遞引數也相同即最終執行相同的sql語句,第一次執行完畢會將資料庫中查詢的資料寫到快取(記憶體),第二次會從快取中獲取資料將不再從資料庫查詢,從而提高查詢效率。Mybatis預設沒有開啟二級快取需要在setting全域性引數中配置開啟二級快取。

二級快取區域是根據mapper的namespace劃分的,相同namespace的mapper查詢資料放在同一個區域,如果使用mapper代理方法每個mapper的namespace都不同,此時可以理解為二級快取區域是根據mapper劃分。
每次查詢會先從快取區域找,如果找不到從資料庫查詢,查詢到資料將資料寫入快取。
Mybatis內部儲存快取使用一個HashMap,key為hashCode+sqlId+Sql語句。value為從查詢出來對映生成的java物件
sqlSession執行insert、update、delete等操作commit提交後會清空快取區域。

開啟二級快取:

<setting name="cacheEnabled" value="true"/>