Mybatis進(jìn)階總結(jié)
一·、#{}和${}的區(qū)別是什么?
1. #將傳入的數(shù)據(jù)都當(dāng)成一個(gè)字符串诅挑,會(huì)對(duì)自動(dòng)傳入的數(shù)據(jù)加一個(gè)雙引號(hào)。如:order by #user_id#泛源,如果傳入的值是111,那么解析成sql時(shí)的值為order by "111", 如果傳入的值是id拔妥,則解析成的sql為order by
"id".2. $將傳入的數(shù)據(jù)直接顯示生成在sql中。如:order by $user_id$达箍,如果傳入的值是111,那么解析成sql時(shí)的值為order by user_id, 如果傳入的值是id没龙,則解析成的sql為order by id.3. #方式能夠很大程度防止sql注入。4.$方式無(wú)法防止Sql注入幻梯。5.$方式一般用于傳入數(shù)據(jù)庫(kù)對(duì)象兜畸,例如傳入表名。6.一般能用#的就別用$.MyBatis排序時(shí)使用order by 動(dòng)態(tài)參數(shù)時(shí)需要注意碘梢,用$而不是#咬摇。
使用#{}格式的語(yǔ)法在mybatis中使用Preparement語(yǔ)句來(lái)安全的設(shè)置值。這樣做的好處是:更安全煞躬,更迅速肛鹏,通常也是首選做法逸邦。不過(guò)有時(shí)你只是想直接在 SQL 語(yǔ)句中插入一個(gè)不改變的字符串。比如在扰,像 ORDER BY缕减,你可以這樣來(lái)使用:ORDER BY ${columnName},此時(shí)MyBatis 不會(huì)修改或轉(zhuǎn)義字符串芒珠。
二桥狡、Mybatis是如何進(jìn)行分頁(yè)的?分頁(yè)插件的原理是什么皱卓?
1. SQL 分頁(yè)
<select
id="queryStudentsBySql" parameterType="map"
resultMap="studentmapper">?
?select * from student limit #{currIndex} , #{pageSize}
</select>
2. 使用攔截器分頁(yè)
創(chuàng)建攔截器裹芝,攔截mybatis接口方法id以ByPage結(jié)束的語(yǔ)句。通過(guò)自定義插件的形式實(shí)現(xiàn)分頁(yè)娜汁,也是最好的嫂易,也叫做分頁(yè)攔截器。實(shí)現(xiàn)步驟如下:插件支持MySQL和Oracle兩種數(shù)據(jù)庫(kù)掐禁,通過(guò)方法名關(guān)鍵字ListPage去匹配怜械,有才進(jìn)行分頁(yè)處理,并且不用在Mapping中寫分頁(yè)代碼傅事。
3. RowBounds分頁(yè)
Mybatis使用RowBounds對(duì)象進(jìn)行分頁(yè)缕允,它是針對(duì)ResultSet結(jié)果集執(zhí)行的內(nèi)存分頁(yè),而非物理分頁(yè)享完,可以在sql內(nèi)直接書寫帶有物理分頁(yè)的參數(shù)來(lái)完成物理分頁(yè)功能灼芭,也可以使用分頁(yè)插件來(lái)完成物理分頁(yè)有额。數(shù)據(jù)量小時(shí)般又,RowBounds不失為一種好辦法。但是數(shù)據(jù)量大時(shí)巍佑,實(shí)現(xiàn)攔截器就很有必要了茴迁。
分頁(yè)插件的基本原理是使用Mybatis提供的插件接口,實(shí)現(xiàn)自定義插件萤衰,在插件的攔截方法內(nèi)攔截待執(zhí)行的sql堕义,然后重寫sql,根據(jù)dialect方言脆栋,添加對(duì)應(yīng)的物理分頁(yè)語(yǔ)句和物理分頁(yè)參數(shù)倦卖。舉例:select * from student,攔截sql后重寫為:select t.* from (select * from student)t?limit 0椿争,10
三怕膛、簡(jiǎn)述Mybatis的插件運(yùn)行原理,以及如何編寫一個(gè)插件秦踪。
插件原理
在四大對(duì)象創(chuàng)建的時(shí)候
1. 每個(gè)創(chuàng)建出來(lái)的對(duì)象不是直接返回的褐捻,而是interceptorChain.pluginAll(parameterHandler)掸茅。
2. 獲取到所有的Interceptor(攔截器)(插件需要實(shí)現(xiàn)的接口);調(diào)用interceptor.plugin(target);返回target包裝后的對(duì)象柠逞。
3. 插件機(jī)制昧狮,我們可以使用插件為目標(biāo)對(duì)象創(chuàng)建一個(gè)代理對(duì)象;AOP(面向切面)我們的插件可以為四大對(duì)象創(chuàng)建出代理對(duì)象板壮;代理對(duì)象就可以攔截到四大對(duì)象的每一個(gè)執(zhí)行逗鸣。
插件編寫
1、編寫Interceptor的實(shí)現(xiàn)類
2绰精、使用@Intercepts注解完成插件簽名
3慕购、將寫好的插件注冊(cè)到全局配置文件中
四、Mybatis 都有哪些動(dòng)態(tài)sql茬底?動(dòng)態(tài)sql的執(zhí)行原理沪悲?
MyBatis的動(dòng)態(tài)SQL是基于OGNL表達(dá)式的,它可以幫助我們方便的在SQL語(yǔ)句中實(shí)現(xiàn)某些邏輯阱表。
MyBatis中用于實(shí)現(xiàn)動(dòng)態(tài)SQL的元素主要有:
動(dòng)態(tài) SQL 執(zhí)行原理為殿如,內(nèi)部使用OGNL的表達(dá)式,從 SQL 參數(shù)對(duì)象中計(jì)算表達(dá)式的值最爬,根據(jù)表達(dá)式的值動(dòng)態(tài)拼接 SQL 涉馁,以此來(lái)完成動(dòng)態(tài) SQL 的功能。
五爱致、MyBatis與Hibernate有哪些不同洁仗?
1. hibernate是全自動(dòng),而mybatis是半自動(dòng)
hibernate完全可以通過(guò)對(duì)象關(guān)系模型實(shí)現(xiàn)對(duì)數(shù)據(jù)庫(kù)的操作评姨,擁有完整的JavaBean對(duì)象與數(shù)據(jù)庫(kù)的映射結(jié)構(gòu)來(lái)自動(dòng)生成sql盏道。而mybatis僅有基本的字段映射,對(duì)象數(shù)據(jù)以及對(duì)象實(shí)際關(guān)系仍然需要通過(guò)手寫sql來(lái)實(shí)現(xiàn)和管理互艾。
2. hibernate數(shù)據(jù)庫(kù)移植性遠(yuǎn)大于mybatis
hibernate通過(guò)它強(qiáng)大的映射結(jié)構(gòu)和hql語(yǔ)言试和,大大降低了對(duì)象與數(shù)據(jù)庫(kù)(oracle、mysql等)的耦合性纫普,而mybatis由于需要手寫sql阅悍,因此與數(shù)據(jù)庫(kù)的耦合性直接取決于程序員寫sql的方法,如果sql不具通用性而用了很多某數(shù)據(jù)庫(kù)特性的sql語(yǔ)句的話昨稼,移植性也會(huì)隨之降低很多节视,成本很高。
3. hibernate擁有完整的日志系統(tǒng)假栓,mybatis則欠缺一些
hibernate日志系統(tǒng)非常健全寻行,涉及廣泛,包括:sql記錄但指、關(guān)系異常寡痰、優(yōu)化警告抗楔、緩存提示、臟數(shù)據(jù)警告等拦坠;而mybatis則除了基本記錄功能外连躏,功能薄弱很多。
4. mybatis相比hibernate需要關(guān)心很多細(xì)節(jié)
hibernate配置要比mybatis復(fù)雜的多贞滨,學(xué)習(xí)成本也比mybatis高入热。但也正因?yàn)閙ybatis使用簡(jiǎn)單,才導(dǎo)致它要比hibernate關(guān)心很多技術(shù)細(xì)節(jié)晓铆。mybatis由于不用考慮很多細(xì)節(jié)勺良,開(kāi)發(fā)模式上與傳統(tǒng)jdbc區(qū)別很小,因此很容易上手并開(kāi)發(fā)項(xiàng)目骄噪,但忽略細(xì)節(jié)會(huì)導(dǎo)致項(xiàng)目前期bug較多尚困,因而開(kāi)發(fā)出相對(duì)穩(wěn)定的軟件很慢,而開(kāi)發(fā)出軟件卻很快链蕊。hibernate則正好與之相反事甜。但是如果使用hibernate很熟練的話,實(shí)際上開(kāi)發(fā)效率絲毫不差于甚至超越mybatis滔韵。
5. sql直接優(yōu)化上逻谦,mybatis要比hibernate方便很多
由于mybatis的sql都是寫在xml里,因此優(yōu)化sql比hibernate方便很多陪蜻。而hibernate的sql很多都是自動(dòng)生成的邦马,無(wú)法直接維護(hù)sql;雖有hql宴卖,但功能還是不及sql強(qiáng)大滋将,見(jiàn)到報(bào)表等變態(tài)需求時(shí),hql也歇菜嘱腥,也就是說(shuō)hql是有局限的耕渴;hibernate雖然也支持原生sql,但開(kāi)發(fā)模式上卻與orm不同齿兔,需要轉(zhuǎn)換思維,因此使用上不是非常方便础米》治總之寫sql的靈活度上hibernate不及mybatis。