首先Mybatis是一個優(yōu)秀的持久層ORM框架咒程,它對jdbc的操作數據庫的過程進行封裝,使得開發(fā)者只需要關注SQL本身吁伺。不需要花費精力去處理一些重復和繁瑣的步驟涛酗。最后通過java對象和statement中的sql進行映射生成最終執(zhí)行的sql語句。最后由mysql框架執(zhí)行sql并將結果映射成java對象并返回沈跨。
ORM:對象關系映射衫冻,簡單點說就是將數據庫中的表和java中的對象建立映射關系,可以讓我們操作對象來間接的操作數據庫谒出。
半ORM:在查詢關聯(lián)對象或關聯(lián)集合對象時隅俘,需要手動編寫sql來完成邻奠。
MyBatis編程步驟
- 創(chuàng)建SqlSessionFactory
- 通過SqlSessionFactory創(chuàng)建SqlSession
- 通過sqlsession執(zhí)行數據庫操作
- 調用session.commit()提交事務
- 調用session.close關閉會話
MyBatis的工作原理
- 讀取MyBatis配置文件。(獲取MyBatis的運行環(huán)境等信息)
- 加載映射文件为居。(SQL映射文件碌宴,其中配置了操作數據庫的SQL語句)
- 構造會話工廠:通過MyBatis的環(huán)境等配置信息構建會話工廠SqlSessionFactory
- 創(chuàng)建會話對象:有會話工廠創(chuàng)建SqlSession對象,該對象包括了執(zhí)行SQL語句的所有方法
- Executor執(zhí)行器:根據SqlSession傳遞的參數動態(tài)的生成需要執(zhí)行的SQL語句蒙畴,同時負責查詢緩存的維護
- Mappedstatement對象:用于存儲要映射的SQL語句的id贰镣、參數等信息
- 輸入參數映射:參數類型可以為Map、List等集合類型也可以使用基本數據類型和POJO類型
- 輸出結果映射:和輸入類似膳凝。
MyBatis的優(yōu)點
- 基于SQL語句編程碑隆,相當靈活。SQL寫在XML中蹬音,解除sql與程序代碼的耦合上煤,便于統(tǒng)一管理。提供XML標簽,支持編寫動態(tài)SQL語句,并可重用
- 消除了 JDBC 大量冗余的代碼狰域,不需要手動開關連接;
- 很好的與各種數據庫兼容
- 能夠與 Spring 很好的集成独泞;
- 提供映射標簽,支持對象與數據庫的 ORM 字段關系映射苔埋;提供對象關系映射標簽懦砂,支持對象關系組件維護。
MyBatis框架的缺點
- SQL 語句的編寫工作量較大组橄,尤其當字段多孕惜、關聯(lián)表多時,對開發(fā)人員編寫SQL 語句的功底有一定要求晨炕。
- SQL 語句依賴于數據庫衫画,導致數據庫移植性差,不能隨意更換數據庫瓮栗。
MyBatis與Hibernate有哪些不同
- MyBatis是一個半ORM框架削罩,需要自己編寫sql語句,靈活性高费奸,但是需要自定義多套sql映射文件弥激,工作量大
- Hibernate數據庫無關性好,節(jié)省代碼愿阐,提高效率
#{}和${}的區(qū)別
- #{}:是預編譯處理微服,會把sql中的#{}替換為?缨历,調用PreoaredStatement的set方法來賦值
-
{}替換為變量的值丛肮。
使用#{}可以有效的防止SQL注入赡磅,提高系統(tǒng)的安全性 。
當實體類的屬性名和表中的字段名不一致如何處理
通過在查詢的sql語句中定義字段名的別名宝与,讓字段名的別名和實體類的屬性名一致焚廊。
通過<resultMap>類映射字段名和實體類屬性名的一一對應的關系
模糊查詢like怎么編寫
- 在Java代碼中添加sql通配符
- 在sql語句中拼接通配符(但是會引起sql注入問題)
通常一個Xml映射文件,都會寫一個Dao接口與之對應习劫。那么Dao接口的工作原理是什么咆瘟。
Dao接口就是Mapper接口。
- 接口的全限定名就是映射文件的namespace的值
- 接口的方法名就是映射文件中Mapper的Statement的id值
- 接口方法內的參數就是傳遞給sql的參數
Mapper接口是沒有實現類的诽里,當調用接口方法的時候袒餐,接口的全限定名+方法名拼接字符串作為key值,可以唯一定位一個MapperStatement须肆。在MyBatis中匿乃,每一個<select>桩皿、<insert>豌汇、<update>、<delete>標簽都會被解析為一個MapperStatement對象
Dao接口的方法泄隔,參數不同時拒贱,方法能重載嗎
Mapper接口里的方法,是不能重載的佛嬉,因為使用全限定名+方法名的保存和尋找策略逻澳。所以不能重載。
Mapper接口的工作原理是JDK動態(tài)代理暖呕,MyBatis運行時會使用JDK動態(tài)代理為Mapper接口生成代理對象proxy斜做,代理對象會攔截接口方法,轉而執(zhí)行MapperStatement所代表的sql湾揽,然后將sql執(zhí)行結果返回瓤逼。
MyBatis是如何進行分頁的以及分頁插件的原理是什么
MyBatis使用RowBounds對象進行分頁,它是針對ResultSet結果集執(zhí)行的內存分頁库物,而非物理分頁霸旗。可以在sql內直接書寫帶有物理分頁的參數來完成物理的分頁功能戚揭,或者使用分頁插件來完成物理分頁
分頁插件的基本原理就是使用MyBatis提供的插件接口诱告,實現自定義插件,在插件的攔截方法內攔截待執(zhí)行的sql民晒,然后重寫sql精居,根據dialect锄禽,添加對應的物理分頁語句和物理分頁參數。
Mybati是如何將sql執(zhí)行機構封裝為對象并返回的箱蟆?有哪些映射形式
- 使用<resultMap>標簽沟绪,逐一定義數據庫列名和對象屬性名之間的映射關系。
- 使用sql列的別名功能空猜,將列別名書寫為對象屬性名
有了列名和屬性名的映射關系后绽慈,MyBatis通過反射創(chuàng)建對象,同時使用反射給對象的屬性逐一賦值并返回辈毯,那些找不到映射關系的屬性坝疼,是無法完成賦值的
如何進行批量插入
如何獲取自動生成的主鍵值
- 使用JDBC內置方法
- 插入后查詢獲取
- 插入前查詢獲取主鍵
如何在mapper中傳遞多個參數
- Dao層函數
- 使用@param注解
- 多個參數封裝成map
MyBatis動態(tài)sql
MyBatis動態(tài)sql可以在Xml映射文件內,以標簽的形式編寫動態(tài)sql谆沃,執(zhí)行原理是根據表達式的值完成邏輯判斷并動態(tài)拼接sql功能
MyBatis提供了九種sql標簽
- trim
- where
- set
- foreach
- if
- choose
- when
- otherwise
- bind
XML文件標簽
- select
- insert
- update
- delete
- resultMap
- parameterMap
- sql
- include
- selectKey
MyBatis的Xml映射文件中钝凶,不同的Xml文件id是否可以重復
如果配置了namespace那么id可以重復,要是沒有配置namespace唁影,id就不可以重復
MyBatis實現一對一有幾種方式
聯(lián)合查詢
- 幾個表聯(lián)合查詢耕陷,只查詢一次,通過配置collection節(jié)點
嵌套查詢
- 先查一個表据沈,再根據查出的id去另外一個表里查詢數據哟沫,也是通過配置collection,但是另外一個表的查詢通過select節(jié)點配置
MyBatis是否支持延遲加載锌介,以及如何實現
Mybatis僅支持association關聯(lián)對象和collection關聯(lián)集合對象的延遲加載嗜诀。可以通過配置lazyLoadingEnabled來進行配置孔祸。
原理
使用 CGLIB 創(chuàng)建目標對象的代理對象隆敢,當調用目標方法時,進入攔截器方法崔慧,比如調用 a.getB().getName()拂蝎,攔截器 invoke()方法發(fā)現 a.getB()是null 值,那么就會單獨發(fā)送事先保存好的查詢關聯(lián) B 對象的 sql惶室,把 B 查詢上來温自,然后調用 a.setB(b),于是 a 的對象 b 屬性就有值了拇涤,接著完成 a.getB().getName()方法的調用捣作。這就是延遲加載的基本原理。
MyBatis的緩存
- 一級緩存: 基于 PerpetualCache 的 HashMap 本地緩存鹅士,其存儲作用域為Session券躁,當 Session flush 或 close 之后,該 Session 中的所有 Cache 就將清空,默認打開一級緩存也拜。
- 二級緩存與一級緩存其機制相同以舒,默認也是采用 PerpetualCache,HashMap存儲慢哈,不同在于其存儲作用域為 Mapper(Namespace)蔓钟,并且可自定義存儲源,如 Ehcache卵贱。默認不打開二級緩存滥沫,要開啟二級緩存,使用二級緩存屬性類需要實現 Serializable 序列化接口(可用來保存對象的狀態(tài)),可在它的映射文件中配置<cache/> 键俱;
緩存更新
- 進行增刪改
- 調用清除方法
- 設置清除屬性
MyBatis的接口綁定兰绣,以及實現方式
接口綁定:就是在MyBatis中任意定義接口,然后把接口里面的方法和SQL語句進行綁定编振,我們在使用的時候直接調用接口方法即可
實現方式
- 通過注解綁定
- 通過xml里面寫sql語句來綁定缀辩,需要指定xml中namespace必須為接口的全路徑名。
Mybatis的mapper接口調用時有哪些要求
- Mapper接口的方法名和mapper.xml中sql的id相同
- Mapper 接口方法的輸入參數類型和 mapper.xml 中定義的每個 sql 的parameterType 的類型相同
- Mapper 接口方法的輸出參數類型和 mapper.xml 中定義的每個 sql 的resultType 的類型相同
- Mapper.xml 文件中的 namespace 即是 mapper 接口的類路徑
Mybatis 的插件運行原理踪央,以及如何編寫一個插件臀玄。
Mybatis 僅可以編寫針對 ParameterHandler、ResultSetHandler畅蹂、StatementHandler健无、Executor 這 4 種接口的插件,Mybatis 使用 JDK 的動態(tài)代理魁莉,為需要攔截的接口生成代理對象以實現接口方法攔截功能睬涧,每當執(zhí)行這 4 種接口對象的方法時募胃,就會進入攔截方法旗唁,具體就是 InvocationHandler 的 invoke()方法,當然痹束,只會攔截那些你指定需要攔截的方法检疫。
編寫插件:實現 Mybatis 的 Interceptor 接口并復寫 intercept()方法,然后在給插件編寫注解祷嘶,指定要攔截哪一個接口的哪些方法即可屎媳,記住,別忘了在配置文件中配置你編寫的插件论巍。
預編譯
定義
SQL預編譯是指數據庫驅動在發(fā)送SQL語句和參數給DBMS之前對SQL語句進行編譯烛谊,這樣DBMS執(zhí)行SQL時,就不需要重現編譯
預編譯作用
可以優(yōu)化SQL的執(zhí)行嘉汰。預編譯后的大多數SQL可以直接運行丹禀,同時預編譯語句對象可以重復利用。還可以防止SQL注入
MyBatis有哪些Executor執(zhí)行器,他們之間的區(qū)別是什么
有三種基本的Executor執(zhí)行器:SimpleExecutor双泪、ReuseExxecutor持搜、BatchExecutor
SimpleExecutor
每執(zhí)行一次update或者select就開啟一個Statement對象,用完就立即關閉
ReuseRxecutor
執(zhí)行update或者select焙矛,以sql為key查找Statement對象葫盼。為了重復使用Statement對象
BatchExecutor
執(zhí)行update,將所有sql都添加到批處理中村斟,等待同一執(zhí)行贫导。其魂村了多個Statement對象。
當實體類中的屬性名和表中的字段名不一樣蟆盹,怎么辦
- 通過在查詢的SQL語句中定義字段名的別名脱盲,讓字段名和實體類的屬性名一致
- 通過resultMap來映射字段名和實體類屬性名的一一對應的關系
ResultType和ResultMap的區(qū)別
首先MyBatis在查詢進行select映射的時候,返回類型可以用resultType也可以用resultMap日缨,其中resultType是直接表示返回類型的钱反,而resultMap則是對外部ResultMap的引用。這兩不能同時存在
在MyBatis進行查詢映射的時候匣距,其實查詢出來的每一個屬性都是放在一個對應的Map中面哥,鍵是屬性名、值是對應的值毅待。
最后
- 如果覺得看完有收獲尚卫,希望能關注一下,順便給我點個贊尸红,這將會是我更新的最大動力吱涉,感謝各位的支持
- 歡迎各位關注我的公眾號【java冢狐】,專注于java和計算機基礎知識外里,保證讓你看完有所收獲怎爵,不信你打我
- 求一鍵三連:點贊、轉發(fā)盅蝗、在看鳖链。
- 如果看完有不同的意見或者建議,歡迎多多評論一起交流墩莫。感謝各位的支持以及厚愛芙委。
——我是冢狐,和你一樣熱愛編程狂秦。
歡迎關注公眾號“ Java冢狐”灌侣,獲取最新消息