最近讀了《深入淺出Mybatis》,感覺非常適合新手入手,或者剛工作一兩年,接觸到Mybatis,裏面介紹了很多小技巧,便於在開發過程中使用,以下是我的一些讀後感。
1.什麼是ORM模型
ORM模型就是數據庫的表和簡單Java對象(Plian Ordinary Java Object,簡稱POJO)的映射關係模型,它主要解決數據庫數據和POJO對象的相互映射。
2. 說說Hibernate
Hibernate是建立在若干POJO通過XML映射文件(或註解)提供的規則映射到數據庫表上的。換句話說,我們可以通過POJO直接操作數據庫的數據,它提供的是一種全表映射的模型。
Hibernate的缺點?
1)全表映射帶來的不便,比如更新時需要發送所有的字段
2)無法根據不同的條件組裝不同的SQL,雖然可以通過HQL拼接SQL
3)對多表關聯和複雜的SQL查詢支持較差
4)不能有效的支持存儲過程
5)不支持表名稱動態
6)表字段動態或者不固定,則無法實現
7)HQL的性能較差,在大型互聯網中需要優化SQL
3. Mybatis
Mybatis的前身是Apache的一個開源項目iBatis,是一個基於Java的持久層框架。Mybatis所需要提供的映射文件包含以下三個部分:
1)SQL
2) 映射規則
3) POJO
Mybatis幾乎開源代替JDBC,擁有動態列、動態表名、存儲過程等都支持,同時提供了簡易的緩存、日誌、級聯。但是他的缺點是需要你提供映射規則和SQL,相對於Hibernate的工作量大一些。
Mybatis的基本構成及生命週期
1) SqlSessionFactoryBuilder(構造器),它會根據配置信息或者代碼來生成SqlSessionFactory(工廠接口)。
SqlSessionFactoryBuilder是利用XML或者Java編碼獲得資源來構建的SqlSessionFactory的,通過它可以構建多個SqlSessionFactory。它的作用就是一個構建器,一旦我們構建了SqlSessionFactory,他的作用就已經完結,我們應該毫不猶豫的將其收回,生命週期只存在方法的局部,他的作用就是生產SqlSessionFactory對象。
2) SqlSessionFactory:依靠工廠來生成SqlSession(會話)。
SqlSessionFactory的作用是創建SqlSession,而SqlSession就是一個會話,相當於JDBC中的Connection對象,每次應用程序訪問數據庫,我們就要通過SqlSessionFactory創建的SqlSession,所以SqlSessionFactory應該在Mybatis應用的整個生命週期中。爲了減少數據庫的連接,我們採用SqlSessionFactory是單例。
3) SqlSession:是一個既可以發送SQL去執行並返回結果,也可以獲取Mapper的接口。
SqlSession是一個會話,相當於JDBC中的一個Connection對象,他的生命週期應該是在請求數據庫處理事務的過程中。它是一個線程不安全的對象,每次創建的SqlSession都必須及時關閉它。
4) SQL Mapper:它是Mybatis新設計的組件,它是由一個Java接口和XML文件(或者註解)構成的,需要給出對應的SQL和映射規則。它負責發送SQL去執行,並返回結果。
Mapper是一個接口,而沒有任何實現類,他的作用就是發生SQL,然後返回我們需要的結果,或者執行SQL從而修改數據庫的數據,因此它應該在一個SqlSession事務方法之內,是一個方法級別的東西。
4. Mybatis bind元素
bind元素的作用是通過OGNL表打死去自定義一個上下文變量,這樣更方便我們使用,在我們進行模糊查詢的時候,如果是Mysql數據庫,我們常常用到的是一個concat 用 “%” 和參數相連接,然而在Oracle數據庫則是用連接符“||”,這樣SQL就需要提供兩種方式去實現。
<select id="xxx" resultMap = "xxx">
select * from User where name like concat ('%', #{name}, '%')
</select>
<select id="xxx" resultMap = "xxx">
<bind name="bind_name" value = "'%' + name + '%'"/>
select * from User where name like #{bind_name}
</select>
5. 構建SqlSessionFactory過程
第一步:通過org.apache.ibatis.builder.xml.XMLConfigBuilder解析配置的XML文件,讀出配置參數,並將讀取的數據存入這個org.apache.ibatis.session.Configuration類中,注意:Mybatis幾乎所有的配置都是存在這裏的。
第二步:使用Configuration對象去創建SqlSessionFactory.SqlSessionFactory是一個接口,Mybatis默認提供了一個DefaultSqlSessionFactory實現類
6. 構建Configuration
1) 讀取配置文件,包括基礎配置的XML文件和映射器的XML文件
2) 初始化基礎配置,比如Mybatis的別名等,一下重要的類對象,比如,插件、映射器、ObjectFactroy和typeHandler對象
3) 提供單例,爲後續構建SessionFactory服務提供配置的參數
4) 執行一些重要的對象方法,初始化配置信息
當修改sql語句的時候,需要重新加載mapper文件,這個時候可以通過Configuration類來幫助我們實現熱加載,而不需要重啓服務器。
7. SqlSession的四大對象
1、Executor 執行器:由它來調度StatementHandler、ParamenterHandler、ResultHandler等來執行對應的SQL
2、StatementHandler(數據庫會話器)的作用是使用數據庫Statement(PreparedStatement)執行操作,它是四大對象的核心,起到承上啓下的作用。
3、ParamenterHandler(參數處理器)用於SQL對參數的處理。
4、ResultHandler(結果處理器)是進行最後數據集的封裝返回處理的
8. 一條查詢SQL的執行過程
Executor會先調用StatementHandler的prepare()方法預編譯SQL語句,同時設置一些基本運行的參數。然後調用parameterize()方法啓用ParamenterHandler設置參數,完成預編譯。跟着就是執行查詢,最後如果有結果集,就調用ResultHandler封裝結果集返回給調用者。
9. SqlSession運行總結
SqlSession是通過Executor創建StatementHandler來運行的,而StatementHandler要經過下面三步:
1)prepared 預編譯SQL
2)parameterize 設置參數
3)query/update 執行SQL
其中 parameterize 是調用 PreparedStatement的方法去設置的,而參數是跟根據類型處理器typeHandler 去處理的。query/update 方法是通過resultHandler進行處理結果的封裝,如果是update的語句,它就是返回整數,否則它就是通過typeHandler處理結果類型,然後用ObjectFactory提供的規則組裝對象,返回給調用者。
10. 事務隔離級別
1)髒讀 :一個事務能夠讀取另一個事務未提交的數據。
2)讀寫提交:就是一個事務要等另一個事務提交後才能讀取數據。
3)可重複讀:就是在開始讀取數據(事務開啓)時,不再允許修改操作
4)序列化:是最高的事務隔離級別,在該級別下,事務串行化順序執行,可以避免髒讀、不可重複讀與幻讀。但是這種事務隔離級別效率低下,比較耗數據庫性能,一般不使用。
11. spring事務傳播特性:
事務傳播行爲就是多個事務方法相互調用時,事務如何在這些方法間傳播。spring支持7種事務傳播行爲:
propagation_requierd:如果當前沒有事務,就新建一個事務,如果已存在一個事務中,加入到這個事務中,這是最常見的選擇。
propagation_supports:支持當前事務,如果沒有當前事務,就以非事務方法執行。
propagation_mandatory:使用當前事務,如果沒有當前事務,就拋出異常。
propagation_required_new:新建事務,如果當前存在事務,把當前事務掛起。
propagation_not_supported:以非事務方式執行操作,如果當前存在事務,就把當前事務掛起。
propagation_never:以非事務方式執行操作,如果當前事務存在則拋出異常。
propagation_nested:如果當前存在事務,則在嵌套事務內執行。如果當前沒有事務,則執行與propagation_required類似的操作
Spring 默認的事務傳播行爲是 PROPAGATION_REQUIRED,它適合於絕大多數的情況。
12. 分頁插件
自定義先查詢總量,然後再limit查詢
推薦第三方插件:Pagehelper(com.github.pagehelper)