Mybatis 執(zhí)行原理精講

前言
本文主要是介紹下java 持久層框架mybatis核心執(zhí)行原理,首先是介紹下mybatis,就是白話下,嘮嘮嗑,在就是通過一張mybatis執(zhí)行流程圖來介紹下它的核心執(zhí)行流程,最后就是對它的幾個核心組件進(jìn)行介紹了。
白話mybatis
mybatis想必搞java 開發(fā)的同學(xué)都知道吧,一款java 輕量級持久層框架,它主要的作用就是封裝jdbc,簡化了我們對jdbc的使用流程,自從用了mybatis,再也看不到connection了,哈哈哈。
它能夠通過xml配置(現(xiàn)在有注解)進(jìn)行參數(shù)綁定,參數(shù)映射,能夠通過標(biāo)簽動態(tài)拼接sql,增加靈活性,還能夠結(jié)果集映射,結(jié)果集與java實體類進(jìn)行高級映射,就不用我們再咔咔咔的處理結(jié)果集了,只需要配置一下實體與數(shù)據(jù)庫表字段映射即可,大大節(jié)省開發(fā)時間,提高開發(fā)效率。
其實說到j(luò)ava持久層框架,還有一個很出名的框架Hibernate,這個框架更狠,直接Java實體與數(shù)據(jù)庫表進(jìn)行關(guān)系映射,不用寫sql,通過操作java 實體就完事了,Hibernate能夠自動幫你拼接sql,執(zhí)行sql,自動與結(jié)果集映射,各種一對一,一對多,多對多表關(guān)系通過實體體現(xiàn)出來就ok,然后查詢?nèi)軒С鰜怼K且豢钊詣拥膐rm對象關(guān)系映射框架,比起Hibernate 這種全自動orm框架來說mybatis使用稍微繁瑣,需要自己寫sql ,有些高級的映射也需要自己寫,mybatis頂多算個半自動的orm框架,但是mybatis 有個很大的優(yōu)點就是可控,自己寫的sql自己心里有數(shù),你像Hibernate 你如果不懂它底層的執(zhí)行原理,你怎么知道它那一對多,多對多關(guān)系是怎樣查出來的,用了幾個sql查出來的,但是mybatis就不一樣了,你想寫一個連表查的sql就寫個連表查的sql,不想寫連表查,分開寫也ok,更加的靈活,可控。
mybatis執(zhí)行流程介紹
上面稍微介紹了一下mybatis,有提到mybatis其實就是封裝了jdbc,把jdbc那繁瑣的操作幫我們屏蔽掉了,然后就是再做了一些參數(shù)封裝,參數(shù)映射,動態(tài)sql,結(jié)果集映射的事情,常用的大概就這些了。
下面我們就拿springboot整合的mybatis為例子,看看它是一個怎樣的流程。
初始化流程
項目啟動,springboot進(jìn)行自動裝配,創(chuàng)建數(shù)據(jù)源啥的,創(chuàng)建一個mybatis核心組件SqlSessionFactory,創(chuàng)建SqlSessionFactory 的時候要進(jìn)行配置文件解析,xml mapper文件解析,將我們的一些配置與mapper文件中的內(nèi)容解析封裝到一個Configuration的配置類中。
創(chuàng)建一個SqlSessionTemplate的組件,現(xiàn)在這里知道它也是這個時候創(chuàng)建的就可以了,它里面持有SqlSessionFactory。
掃描package找到@Mapper注解標(biāo)注的接口,也就是我們那個dao 接口,封裝成一個個的FactoryBean,這個東西很重要哈,這個FactoryBean 就是工廠bean,能夠創(chuàng)建對應(yīng)的bean對象,也就是創(chuàng)建我們那個dao接口的對象,具體的創(chuàng)建其實就是生成dao接口的動態(tài)代理類了。那什么時候生成dao接口的動態(tài)代理呢?其實是在實例化bean的時候spring才會調(diào)用FactoryBean的getObject方法來生成動態(tài)代理類。
項目初始化的流程我們就介紹完事了,用一張圖總結(jié)一下

就是3件事
創(chuàng)建SqlSessionFactory對象,同時創(chuàng)建congfiguraion對象, 解析配置信息,配置文件,mapper文件到configuration中。
創(chuàng)建SqlSessiontTemplate對象,里面持有SqlSessionFactory對象,同時創(chuàng)建了一個SqlSession代理類。
掃描mapper接口(也就是dao接口),創(chuàng)建動態(tài)代理對象。
執(zhí)行sql流程
執(zhí)行sql流程就熱鬧了,各個組件這個時候就出來了。
我們執(zhí)行sql其實就是執(zhí)行dao某個方法。
下面我們就拿UserDao里面的一個添加user的方法說吧

當(dāng)我們service調(diào)用UserDao執(zhí)行addUser的時候。它其實是調(diào)用的UserDao的一個動態(tài)代理類,就會一個MapperMethod這么一個對象里面的execute方法,就是看看是執(zhí)行insert方法還是update方法,接著就找到SqlSessionTempplate這個類里面的SqlSessionProxy代理類,然后這個代理類就會找到SqlSessionFactory獲取對應(yīng)的SqlSession,其實就是創(chuàng)建SqlSession,然后SqlSession會找到Executer來執(zhí)行,它會胡創(chuàng)建一個StatementHandler的類,做一些獲取連接,創(chuàng)建statement的事情,然后由ParameterHandler 設(shè)置參數(shù),執(zhí)行sql(發(fā)往mysql執(zhí)行sql語句),返回結(jié)果后調(diào)用ResultSetHandler處理結(jié)果集,做結(jié)果集映射啥的(當(dāng)然insert,update,delete語句的話,就不會使用ResultSetHandler做結(jié)果集映射了),這就是粗略的執(zhí)行流程了。
下面我們把這個流程用圖畫出來。

其實核心就是紅框框起來的那些,Executor創(chuàng)建StatementHandler,然后獲取connection數(shù)據(jù)庫連接,創(chuàng)建statement,調(diào)用ParameterHandler設(shè)置參數(shù),將參數(shù)設(shè)置到statement中,接著就是發(fā)送sql給數(shù)據(jù)庫,執(zhí)行sql,最后將結(jié)果集返回,由ResultSetHandler組件進(jìn)行結(jié)果集的映射。
核心組件介紹
上面我們介紹了mybatis初始化流程與執(zhí)行sql語句的核心流程,流程里面也出現(xiàn)了很多組件,接下來我們用最最通俗的語言介紹下這幾個核心組件。
SqlSessionFactory 這個組件里面維護(hù)所有解析好的配置,包括mapper文件,它的核心功能就是創(chuàng)建SqlSession
SqlSession 一次sql執(zhí)行生命周期,所謂生命周期就是執(zhí)行前的操作,執(zhí)行動作,執(zhí)行后的操作,具體的執(zhí)行是由Executor組件干的。
Executor組件的,就是具體干活的,它里面有緩存的一些東西,包括一級緩存,二級緩存,這個后面文章會專門介紹,它創(chuàng)建StatementHandler,調(diào)用StatementHandler 方法獲取去數(shù)據(jù)源中獲取連接,創(chuàng)建statement,執(zhí)行sql等。
StatementHandler 獲取連接,創(chuàng)建statement, 調(diào)用ParameterHandler 設(shè)置參數(shù),執(zhí)行sql,調(diào)用ResultSetHandler組件處理結(jié)果集,進(jìn)行結(jié)果集映射等等。
ParameterHandler 這個就是往statement里面設(shè)置參數(shù),我們使用PreparedStatement 防止sql注入的時候,會將sql里面的某些參數(shù)值設(shè)置成?(問號),接著就會將真正的值設(shè)置進(jìn)去,ParameterHandler 就是干這個事情的。
ResultSetHandler 就是處理結(jié)果集的,將sql執(zhí)行的結(jié)果集進(jìn)行實體映射啥的。
總結(jié)
好了,到這里我們mybatis執(zhí)行原理就結(jié)束了,首先我們介紹了一下mybatis,跟另一款持久層框架Hibernate做了下簡單的對比,然后介紹了一下springboot整合mybatis的項目mybatis初始化都干了些啥,執(zhí)行某個sql(dao方法)的時候,他的一個執(zhí)行流程,最后我們對執(zhí)行流程里的一些核心組件做了一下簡單的介紹。
作者:$碼出未來
出處:blog.csdn.net/yuanshangshenghuo/article/details/119007391
關(guān)注GitHub今日熱榜,專注挖掘好用的開發(fā)工具,致力于分享優(yōu)質(zhì)高效的工具、資源、插件等,助力開發(fā)者成長!
點個在看,你最好看
