第一部分:自定義持久層框架
1.1 原始JDBC撰寫步驟及存在問題
1.2 問題解決思路
1.3 自定義框架設計
1.4 自定義框架實作
1.5 自定義框架優化
第二部分:Mybatis相關概念
第三部分:Mybatis基本應用
3.1 開發步驟
3.2 Mybatis映射檔案概述
3.3 MyBatis核心組態檔層級關系
3.4 Mybatis核心組態檔SqlSessionConfig.xml決議
3.5 mybatis 常用API介紹
3.6 Mybatis的Dao層實作方式
3.7 動態sql陳述句
第四部分:Mybatis復雜映射開發
第五部分:Mybatis注解開發
第六部分:Mybatis快取
6.1 一級快取
6.2 二級快取
6.3 二級快取整合redis
第七部分:Mybatis插件
7.1 插件介紹
7.2 Mybatis插件原理
7.3 自定義插件
7.4 pageHelper分頁插件
7.5 通用Mappper
第八部分:Mybatis架構原理
8.1 功能架構分層
8.2 主要構件及其關系
第九部分: Mybatis原始碼決議
第一部分:自定義持久層框架
1.1 原始JDBC撰寫步驟及存在問題
撰寫步驟(查詢):
加載資料庫驅動--》通過驅動管理類獲取資料庫連接--》定義sql陳述句--》獲取預編譯statement--》設定引數--》向資料庫發出sql執行查詢,查詢結果集--》遍歷結果集,封裝物體--》關閉資源
存在問題:
1)頻繁的創建、釋放資料庫連接會造成系統資源的浪費,從而影響系統性能,
2)sql陳述句存在硬編碼、使用preparedStatement向有占位符傳引數存在硬編碼、結果集決議的時候存在硬編碼,造成代碼不易維護,
1.2 問題解決思路
1)使用資料庫連接池初始化連接資源
2)將sql抽取到xml檔案中
3)使用反射、內省等底層技術,將資料庫欄位與物體屬性進行自動映射,
1.3 自定義框架設計
使用端:
提供核心組態檔:
SqlMapConfig.xml:存放資料源資訊,引入Mapper.xml
Mapper.xml:存放sql陳述句的配置資訊
框架端:本質是對jdbc的封裝
1)讀取組態檔
首先以流的形式讀取組態檔,然后將位元組輸入流存進兩個javabean物件,方便后續的操作,
兩個javabean如下:
Configuration:存放資料庫基本資訊,Map<namespace+"."+id,mappedstatement>
MappedStatement:id標識,sql陳述句,statement型別(select,insert,update,delete),輸入引數java型別,輸出引數java型別
2)決議組態檔
創建SqlSessionFactoryBuilder類
方法: SqlSessionFactory build()
第一:使用dom4j決議組態檔,將決議出來的內容封裝到Configuration和MappedStatement中
第二:創建SqlSessionFactory的實作類DefaultSqlSessionFactory
3)創建SqlSessionFactory
方法:openSession() :獲取SqlSession介面的實作類實體物件
4)創建SqlSession介面及實作類DefaultSqlSession,主要封裝crud方法
方法:selectList(String stateMentId, Object param):查詢所有
selectOne(String stateMentId, Object param):查詢單個
...
具體實作:封裝jdbc完成對資料庫的操作
5)Executor,實作類SimpleExecutor
涉及到的設計模式:
Builder構建者模式,工廠模式,代理模式
1.4 自定義框架實作
動手敲一下代碼,,,
1.5 自定義框架優化
上述自定義框架存在的問題:
1) dao的實作類里存在重復代碼,整個操作的程序模板重復(創建sqlSession,呼叫sqlSession,關閉sqlSession)
2) dao實作類中存在硬編碼,呼叫sqlSession方法時,引數statement的id硬編碼
解決方案:使用代理模式來創建介面的代理物件(不管代理物件呼叫何方法,都會轉到invoke())
代理模式注意事項:
- Mapper.xml檔案中的namespace與Mapper介面中的全限定名相同
- Mapper.xml中定義的每個statement的id與Mapper介面的方法名相同
- Mapper.xml中定義的每個sql的parameterType與Mapper介面的輸入引數型別相同
- Mapper.xml中定義的每個sql的resultType與Mapper介面的輸出引數型別相同
Mapper 介面的作業原理是JDK動態代理,Mybatis運行時會使用JDK動態代理為Mapper介面生成代理物件proxy,代理物件會攔截介面方法,根據類的全限定名+方法名,唯一定位到一個MapperStatement并呼叫執行器執行所代表的sql,然后將sql執行結果回傳,
Mapper介面里的方法,是不能多載的,因為是使用 全限名+方法名 的保存和尋找策略,
第二部分:Mybatis相關概念
Mybatis是一款優秀的基于ORM(物件關系映射)的半自動化輕量級的持久層框架,SQL與JAVA編碼分離,
第三部分:Mybatis基本應用
3.1 開發步驟
1) 添加Mybatis坐標
2)創建user資料庫表
3)撰寫user物體類
4)撰寫映射檔案UserMapper.xml
5)撰寫核心組態檔SqlMapConfig.xml
6)撰寫測驗類
注:增加,更新,洗掉操作涉及資料庫變化,要使用sqlSession物件顯示的提交事務,
即sqlSesison.commit();因為sqlSessionFactory.openSession()默認開啟一個事務,但不會主動提交,
如果需要它主動提交,需要呼叫它的有參構造方法sqlSessionFactory.openSession(true).
3.2 Mybatis映射檔案概述

3.3 MyBatis核心組態檔層級關系

3.4 Mybatis核心組態檔SqlSessionConfig.xml決議
1)environments標簽
資料庫環境的配置,支持多配置

其中:
事務管理器transactionManagee有兩種型別:JDBC和MANAGED
資料源datasource有三種型別:POOLED,UNPOOLED,JNDI
2)mapper標簽
該標簽的作用是加載映射,加載方式如下:
3)properties標簽
用于加載外部的properties檔案,習慣上將資料源的資訊單獨抽取成一個properties組態檔
4)typeAliases標簽
型別別名
3.5 mybatis 常用API介紹
SqlSession工廠構建器SqlSessionFactoryBuilder
常用API: SqlSessionFactory build(IputStream, inputStream)
SqlSession工廠物件SqlSessionFactory
常用API:openSession()(需要手動提交事務)或openSesison(true)(自動提交事務)
SqlSession會話物件
常用APi:增刪改查方法,,,
3.6 Mybatis的Dao層實作方式
1)傳統開發方式
需要撰寫dao介面及實作類(實作類有重復代碼,且statementId存在硬編碼問題)
2)代理開發方式
開發人員只需要撰寫Mapper介面(相當于dao介面),由Mybatis框架根據介面定義生成動態代理物件,代理物件的方法體同上面的dao介面實作類的方法,
Mapper介面需要遵循以下規范:
- Mapper.xml檔案中的namespace與Mapper介面中的全限定名相同
- Mapper.xml中定義的每個statement的id與Mapper介面的方法名相同
- Mapper.xml中定義的每個sql的parameterType與Mapper介面的輸入引數型別相同
- Mapper.xml中定義的每個sql的resultType與Mapper介面的輸出引數型別相同
3.7 動態sql陳述句
and id=#{id}
...
#{id}
sql片段抽取
第四部分:Mybatis復雜映射開發
一對一配置
一對多配置
多對多配置
第五部分:Mybatis注解開發
@Insert:實作新增 @Update:實作更新 @Delete:實作洗掉 @Select:實作查詢 @Result:實作結果集封裝 @Results:可以與@Result 一起使用,封裝多個結果集 @One:實作一對一結果集封裝 @Many:實作一對多結果集封裝
第六部分:Mybatis快取
一級快取和二級快取底層的資料結構都是HashMap
Mybatis默認實作的快取類是PerpetualCahe
自定義快取類必須實作Cache類
6.1 一級快取
Mybatis的一級快取是指SQLSession,一級快取的作用域是SQlSession, Mabits默認開啟一級快取, 在同一個SqlSession中,執行相同的SQL查詢時;第一次會去查詢資料庫,并寫在快取中,第二次會直接從快取中取, 當執行SQL時候兩次查詢中間發生了增刪改的操作,則SQLSession的快取會被清空, 每次查詢會先去快取中找,如果找不到,再去資料庫查詢,然后把結果寫到快取中,
Mybatis的內部快取使用一個HashMap,key(statementId+rowBounds引數+sql陳述句),Value為查詢出來的結果集映射成的java物件, SqlSession執行insert、update、delete等操作commit后會清空該SQLSession快取,

6.2 二級快取
二級快取的原理同一級快取
但二級快取是基于Mapper檔案的namespace的,也就是說多個sqlSession可以共享一個Mapper中的二級快取區域,
并且,如果兩個Mapper的namespace相同,即使是兩個mapper,那么這兩個Mapper中執行sql查詢的資料也將保存到相同的二級快取區域中,
二級快取默認是關閉的,需要手動開啟!!
開啟二級快取步驟:
1)首先在全域組態檔SqlMapConfig.xml檔案中加入以下代碼:
2) 其次在Mapper.xml中開啟快取
< cache>
開啟二級快取后,對應的POJO類需要實作序列化介面serializable,為了將快取資料取出來執行反序列化操作,
因為二級快取資料存盤介質多種多樣,不一定只存在記憶體中,有可能存在硬碟中,如果我們再取這個快取的時候,就需要反序列化了,
當一級快取和二級快取同時存在:先查詢二級快取再查詢一級快取,因為一級快取的實作在BaseExecutor,而二級快取的實作在CachingExecutor,CachingExecutor是BaseExecutor的裝飾器
userCache和flushCache
在statement中設定userCahce = "false"可以禁用當前select陳述句的二級快取,useCahce默認是true,
在statement中設定flushCache="true",可以重繪快取,默認是true,在mapper的同一個namespace中,如果有其它的insert,update,delete操作資料后需要重繪快取,如果不執行快取會存在臟讀,
二級快取的默認實作類是PerpetualCache
6.3 二級快取整合redis
mybatis自帶的二級快取僅支持單服務器作業,無法實作分布式快取,
分布式快取:在幾個不同的服務器之間,我們使用第三方框架,將快取存進第三方框架中(redis,memcached,ehcache),然后無論有多少臺服務器,我們都能從快取中獲取資料,
mybatis提供了一個針對cache介面的redis實作類,該類存在mybatis-redis包中
需要在mapper.xml 中加入cache的型別指向
mybais-redis在存資料的時候,是使用的hash結構,把hash的id作為這個hash的key(hash的key在mybatis中就是mapper中的namespace);
這個mapper中的查詢資料作為hash的filed,需要快取的內容直接使用serializeUtil存盤,serializeUtil和其它序列化類差不多,負責物件的序列化和反序列化,
第七部分:Mybatis插件
7.1 插件介紹
Mybatis四大核心物件:Executor,StatementHandler,ParameterHandler,ResultSetHandler
Mybatis支持用插件對四大核心物件進行攔截,對Mybatis來說,插件就是攔截器,用來增強核心物件的功能,增強功能本質上是借助于底層的動態代理實作的,
換句話說,Mybatis的四大物件都是代理物件,
Mybatis所允許攔截的方法如下:
- 執行器Executor(update,query,commit,rollback等方法)
- Sql語法構建器StatementHandler(prepare,parameterize,batch,updates,query等方法)
- 引數處理器ParameterHandler(getParameterObject,setParameters方法)
- 結果處理器ResultSetHandler(handleResultSets,handleOutputParameters等方法)
7.2 Mybatis插件原理
當我們定義一個插件,并在SqlMapConfig.xml增加插件配置后,這樣Mybatis在啟動的時候就可以加載插件,并保存插件實體到相關物件(InterceptorChain攔截器鏈)中.
待準備作業完成后,Mybatis處于就緒狀態,我們再執行sql的時候,需要先通過DefaultSqlSessionFactory創建SqlSession.
Execoutor實體會在創建SqlSession的程序中被創建,Executor實體被創建完畢之后,Mybatis會通過JDK動態代理為實體生代理類,
這樣,插件邏輯即可以在Executor相關方法呼叫前被呼叫,
7.3 自定義插件
自定義插件需要實作Interceptor介面,并重寫 Object intercept(Invocation invocation)方法和 Object plugin(Object target)及void setProperties(Properties properties)方法

7.4 pageHelper分頁插件
開發步驟:
1)匯入通用的pageHelper坐標
2)在Mybatis核心組態檔SqlMapConfig.xml中配置pageHelper插件
3)測驗分頁資料獲取
7.5 通用Mappper
通用mappper就是為了解決單表的增刪改查,基于mybatis的插件機制,開發人員不需要寫sql,不需要在dao的增加方法,需要寫好物體類,就能支持增刪改查方法,
具體參考老師的筆記!!
第八部分:Mybatis架構原理
8.1 功能架構分層
Mybatis的功能架構可分為三層:
1)API介面層
Mybatis與資料庫互動有兩種方式:
a)使用傳統的Mybatis提供的API
b)使用Mapper的代理方式
2)資料庫處理層
負責具體的sql查找,sql決議,sql執行和執行結果映射等操作,它主要的目的是根據呼叫的請求完成一次性資料庫操作,
3)基礎支撐層
負責最基礎的功能支撐,包括連接管理,事務管理,配置加載和快取處理,
8.2 主要構件及其關系
- SqlSesison :作為Mybatis作業的主要頂層API,表示和資料庫互動的會話,完成必要資料庫的增刪改查功能,
- Executor:Mybatis執行器,是Mybatis調度的核心,負責SQl陳述句的生成和查詢快取的維護
- StatementHandler:封裝了JDBC的statement操作(設定引數,將Statement結果集轉成list集合)
- ParameterHandler:負責對用戶傳遞的引數轉成JDBC Statement所需要的引數
- ResultSetHandler:負責將JDBC回傳的ResultSet結果集轉換成List型別的集合
- TypeHandler:負責Java型別和JDBC資料型別之間的映射和轉換
- MappedStatement:維護了一條
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/285993.html
標籤:架構設計
上一篇:從0開始學架構,前阿里P9技術專家的實戰心法
下一篇:當年,我是如何把微服務落地的