大家好,我是IT修真院深圳分院第01期學(xué)員缩滨,一枚正直純潔善良的web程序員势就。今天給大家分享一下,修真院官網(wǎng)JAVA(職業(yè))任務(wù)1的知識(shí)點(diǎn)——mybatis常用標(biāo)簽和動(dòng)態(tài)查詢脉漏。
1.背景介紹
MyBatis是支持定制化SQL苞冯、存儲(chǔ)過程以及高級(jí)映射的優(yōu)秀的持久層框架。MyBatis避免了幾乎所有的JDBC代碼和手動(dòng)設(shè)置參數(shù)以及獲取結(jié)果集侧巨。MyBatis可以對(duì)配置和原生Map使用簡(jiǎn)單的XML或注解舅锄,將接口和Java的POJOs(Plain Old Java Objects,普通的Java對(duì)象)映射成數(shù)據(jù)庫(kù)中的記錄。
2.知識(shí)剖析
2.1 基本知識(shí)
SqlSessionFactory:每個(gè)基于 MyBatis 的應(yīng)用都是以一個(gè) SqlSessionFactory 的實(shí)例為中心的司忱。SqlSessionFactory的實(shí)例可以通過SqlSessionFactoryBuilder獲得皇忿。而SqlSessionFactoryBuilder則可以從XML配置文件或一個(gè)預(yù)先定制的Configuration的實(shí)例構(gòu)建出SqlSessionFactory的實(shí)例。
SqlSession:SqlSession完全包含了面向數(shù)據(jù)庫(kù)執(zhí)行SQL命令所需的所有方法坦仍。你可以通過SqlSession實(shí)例來直接執(zhí)行已映射的SQL語句鳍烁。
XML配置文件(configuration XML)中包含了對(duì)MyBatis系統(tǒng)的核心設(shè)置,包含獲取數(shù)據(jù)庫(kù)連接實(shí)例的數(shù)據(jù)源(DataSource)和決定事務(wù)作用域和控制方式的事務(wù)管理器(TransactionManager)繁扎。
作用域和生命周期:
SqlSessionFactoryBuilder一旦創(chuàng)建了SqlSessionFactory幔荒,就不再需要它了,因此該實(shí)例的最佳作用域是方法作用域,也就是局部方法變量铺峭。
SqlSessionFactory一旦被創(chuàng)建就應(yīng)該在應(yīng)用的運(yùn)行期間一直存在墓怀,沒有任何理由對(duì)它進(jìn)行清除或重建,因此SqlSessionFactory的最佳作用域是應(yīng)用作用域卫键。
SqlSession:每個(gè)線程都應(yīng)該有它自己的SqlSession實(shí)例傀履。SqlSession的實(shí)例不是線程安全的,因此是不能被共享的莉炉,所以它的最佳的作用域是請(qǐng)求或方法作用域钓账。絕對(duì)不能將SqlSession實(shí)例的引用放在一個(gè)類的靜態(tài)域,甚至一個(gè)類的實(shí)例變量也不行絮宁,也絕不能將SqlSession實(shí)例的引用放在任何類型的管理作用域中梆暮。
2.2 Configuration.xml配置文件
2.2.1 properties標(biāo)簽
包含了mybatis的屬性信息。如果屬性在多個(gè)地方進(jìn)行配置绍昂,mybatis加載順序?yàn)椋?br>
--在properties元素體內(nèi)指定的屬性首先被讀取啦粹。
--然后根據(jù)properties元素中的resource屬性讀取類路徑下屬性文件或根據(jù)url屬性指定的路徑讀取屬性文件,并覆蓋已讀取的同名屬性窘游。
--最后讀取作為方法參數(shù)傳遞的屬性唠椭,并覆蓋已讀取的同名屬性。
從MyBatis 3.4.2開始忍饰,可以為占位符指定一個(gè)默認(rèn)值贪嫂,如:${username:ut_user}"。
2.2.2 settings標(biāo)簽
設(shè)置mybatis的行為艾蓝,通常采用默認(rèn)設(shè)置力崇,若有特殊需要,則在文件中顯式設(shè)置赢织。
2.2.3 typeAliases標(biāo)簽
類型別名是為Java類型設(shè)置一個(gè)短的名字亮靴。它只和XML配置有關(guān),存在的意義僅在于用來減少類完全限定名的冗余于置〖氲酰可以指定一個(gè)包名,MyBatis會(huì)在包名下面搜索需要的Java Bean俱两,可以在Bean上使用注解饱狂。
2.2.4 typeHandlers標(biāo)簽
無論是MyBatis在預(yù)處理語句(PreparedStatement)中設(shè)置一個(gè)參數(shù)時(shí),還是從結(jié)果集中取出一個(gè)值時(shí)宪彩,都會(huì)用類型處理器將獲取的值以合適的方式轉(zhuǎn)換成Java類型休讳。可以重寫類型處理器或創(chuàng)建自定義的類型處理器來處理不支持的或非標(biāo)準(zhǔn)的類型尿孔。
2.2.5 objectFactory標(biāo)簽
MyBatis每次創(chuàng)建結(jié)果對(duì)象的新實(shí)例時(shí)俊柔,它都會(huì)使用一個(gè)對(duì)象工廠(ObjectFactory)實(shí)例來完成筹麸。可以創(chuàng)建自定義的對(duì)象工廠來覆蓋默認(rèn)行為雏婶。
2.2.6 plugins標(biāo)簽
可以在已映射語句執(zhí)行過程中的某一點(diǎn)進(jìn)行攔截調(diào)用物赶。
2.2.7 transactionManager標(biāo)簽
MyBatis中有兩種類型的事務(wù)管理器:
JDBC –這個(gè)配置就是直接使用了JDBC的提交和回滾設(shè)置,它依賴于從數(shù)據(jù)源得到的連接來管理事務(wù)作用域留晚。
MANAGED –讓容器來管理事務(wù)的整個(gè)生命周期酵紫,比如JEE應(yīng)用服務(wù)器的上下文。如果使用Spring + MyBatis错维,則沒有必要配置事務(wù)管理器奖地,Spring模塊會(huì)使用自帶的管理器來覆蓋前面的配置。
2.2.8 dataSource標(biāo)簽
dataSource使用標(biāo)準(zhǔn)的JDBC數(shù)據(jù)源接口來配置JDBC連接對(duì)象的資源赋焕。有三種類型的數(shù)據(jù)源:
UNPOOLED—這個(gè)數(shù)據(jù)源的實(shí)現(xiàn)只是每次被請(qǐng)求時(shí)打開和關(guān)閉連接参歹。
POOLED—這種數(shù)據(jù)源的實(shí)現(xiàn)利用“池”的概念將JDBC連接對(duì)象組織起來,避免了創(chuàng)建新的連接實(shí)例時(shí)所必需的初始化和認(rèn)證時(shí)間隆判。
JNDI—這個(gè)數(shù)據(jù)源的實(shí)現(xiàn)是為了能在如EJB或應(yīng)用服務(wù)器這類容器中使用犬庇,容器可以集中或在外部配置數(shù)據(jù)源,然后放置一個(gè)JNDI上下文的引用侨嘀。
2.2.9 mappers標(biāo)簽
用來告訴MyBatis去哪里找映射文件臭挽,可以通過設(shè)置resource、url飒炎、class或指定Java bean包名等埋哟。
2.3 Mapper.xml映射文件
映射文件有幾個(gè)頂級(jí)元素笆豁,按順序?yàn)椋?br>
cache:給定命名空間的緩存配置郎汪。
cache-ref:其他命名空間緩存配置的引用。
resultMap:用來描述如何從數(shù)據(jù)庫(kù)結(jié)果集中來加載對(duì)象闯狱。
sql:可被其他語句引用的可重用語句塊煞赢。
insert、update哄孤、delete照筑、select:分別映射插入、更新瘦陈、刪除凝危、查詢語句。
2.4 動(dòng)態(tài)查詢標(biāo)簽
if晨逝、choose蛾默、otherwise、when:用于在查詢時(shí)有條件地包含where子句的一部分捉貌。
trim支鸡、where冬念、set:用于處理查詢條件語句拼接的情況。
foreach:用于在構(gòu)建IN條件語句的時(shí)候牧挣,對(duì)一個(gè)集合進(jìn)行遍歷急前。
bind:用于創(chuàng)建一個(gè)變量并將其綁定到sql語句上下文中。
以上是一些mybatis常用標(biāo)簽的基本介紹瀑构,具體使用見視頻裆针。
3. 常見問題
實(shí)際使用
4. 解決方案
見使用視頻
5. 編碼實(shí)戰(zhàn)
6. 擴(kuò)展思考
Mybatis與JDBCTemplate
Mybatis可自定義多種操作,在ObjectFactory中,在TypeHandler中,在Plugin中寺晌。這樣方便排查在整個(gè)操作過程中可能出現(xiàn)的問題据块,但是需要寫許多實(shí)現(xiàn)代碼。
JDBCTemplate使用簡(jiǎn)單折剃,也可以自行處理一些操作異常另假,相比之下實(shí)現(xiàn)代碼較少。
7. 參考文獻(xiàn)
參考:Mybatis中文文檔
8. 更多討論
Mybatis實(shí)現(xiàn)更復(fù)雜的操作怕犁,如嵌套查詢边篮、聯(lián)表查詢等
問:為什么一開始運(yùn)行,plugin類中的方法會(huì)直接打印出結(jié)果奏甫?
答:因?yàn)樵赾onfig文件中戈轿,plugin元素設(shè)置了property屬性,實(shí)例化時(shí)則會(huì)首先執(zhí)行setProperties()方法阵子。
問:為什么在demo中執(zhí)行了更新和插入語句思杯,獲取結(jié)果是已經(jīng)更新的結(jié)果,但是用navicat和cmd查看mysql的數(shù)據(jù)卻沒有更新挠进?
答:這個(gè)問題自己也沒搞清楚色乾,在config文件中已經(jīng)把緩存設(shè)置關(guān)掉了,按道理如果操作正常领突,mysql應(yīng)該會(huì)執(zhí)行更新暖璧,實(shí)際結(jié)果卻不是這樣。而且當(dāng)刪除更新和插入操作君旦,單獨(dú)執(zhí)行獲取數(shù)據(jù)澎办,返回的結(jié)果是mysql中原來的數(shù)據(jù),這說明更新和插入操作確實(shí)沒有執(zhí)行到mysql中金砍。
問:會(huì)不會(huì)是plugin類攔截了update方法局蚀?
答:不是,將plugin類從config文件中注釋掉執(zhí)行恕稠,還是同樣的結(jié)果琅绅。
鳴謝
感謝大家觀看
------------------------------------------------------------------------------------------------------------------------
今天的分享就到這里啦,歡迎大家點(diǎn)贊谱俭、轉(zhuǎn)發(fā)奉件、留言宵蛀、拍磚~