Java面試題沖刺第九天--MyBatis
面試題1:你怎么理解ORM框架,常見(jiàn)的ORM框架都有哪些?
正經(jīng)回答:
對(duì)象關(guān)系映射(Object Relational Mapping,簡(jiǎn)稱(chēng)ORM)
,主要實(shí)現(xiàn)程序?qū)ο蟮疥P(guān)系數(shù)據(jù)庫(kù)數(shù)據(jù)的映射。
JAVA編程免不了和數(shù)據(jù)庫(kù)打交道,那么如何高效便捷地操作數(shù)據(jù)庫(kù),也是一個(gè)需要應(yīng)對(duì)的問(wèn)題,原生的基于JDBC的方式非常低效,而且要寫(xiě)一大堆無(wú)用的模板代碼
,不值得選取。ORM是對(duì)JDBC的封裝
,讓我們不需要重復(fù)的造輪子,目前已經(jīng)有很多優(yōu)秀的ORM框架可供使用了,常見(jiàn)的比如Mybatis(batis)、Hibernate、Jpa、Jdo等。
優(yōu)點(diǎn):
- ORM是對(duì)JDBC的封裝,從而解決了JDBC的各種存在問(wèn)題,提高效率
- 使開(kāi)發(fā)更加對(duì)象化
- 可移植性強(qiáng)
- 可以很方便地引入數(shù)據(jù)緩存之類(lèi)的附加功能
缺點(diǎn):
- 自動(dòng)化進(jìn)行關(guān)系數(shù)據(jù)庫(kù)的映射需要消耗少量系統(tǒng)性能。
- 在處理多表聯(lián)查、where條件復(fù)雜之類(lèi)的查詢(xún)時(shí),ORM的語(yǔ)法會(huì)變得復(fù)雜。
市面上主流ORM框架:
- EJB:重量級(jí)、高花費(fèi)的ORM技術(shù),支持JPA,尤其是EJB3低侵入式 的設(shè)·計(jì),增加了Annotation
- Hibernate:開(kāi)源,支持JPA ,被選作JBoss的持久層解決方案
- iBatis:”SQL Mapping”框架,Apache軟件基金組織的子項(xiàng)目,后 轉(zhuǎn)Google Code旗下,ibatis3.x正式更名為Mybatis
- Spring Data JPA:Spring框架中的子模塊
- TopLink:Oracle公司的產(chǎn)品
- Open JPA:Apache軟件基金組織的開(kāi)源項(xiàng)目
追問(wèn)1:大家都在用Mybatis,Mybatis都有哪些優(yōu)勢(shì)?
- Mybatis入門(mén)簡(jiǎn)單;在使用上,對(duì)于熟悉編寫(xiě)SQL的同學(xué)來(lái)說(shuō),基本上是即學(xué)即用。
Mybatis對(duì)jdbc的抽象封裝程度更高
,spring jdbc要想實(shí)現(xiàn)的細(xì)節(jié)很多,例如Mybatis封裝了更多的對(duì)象映射。支持注解
,面對(duì)接口開(kāi)發(fā),效率高,分分鐘解決一個(gè)sql。- 對(duì)于復(fù)雜的SQL,springJDBC編寫(xiě)麻煩,動(dòng)態(tài)SQL語(yǔ)句設(shè)計(jì)也麻煩,相比之下,Mybatis更加靈活且人性化。
- mybatis的高度封裝,使得程序員可專(zhuān)注與業(yè)務(wù)層,開(kāi)發(fā)效率高。所以選擇mybatis的開(kāi)發(fā)公司多。
面試題2:相比較Hibernate與Mybatis,你有哪些看法?
正經(jīng)回答:
Hibernate與MyBatis都可以是通過(guò)SessionFactoryBuider由XML配置文件生成SessionFactory,然后由SessionFactory 生成Session,最后由Session來(lái)開(kāi)啟執(zhí)行事務(wù)和SQL語(yǔ)句。其中SessionFactoryBuider,SessionFactory,Session的生命周期都是差不多的。
Hibernate和MyBatis都支持JDBC和JTA事務(wù)處理。
Mybatis優(yōu)勢(shì)
- MyBatis可以進(jìn)行更為細(xì)致的SQL優(yōu)化,可以減少查詢(xún)字段。
- MyBatis容易掌握,而Hibernate門(mén)檻較高。
Hibernate優(yōu)勢(shì)
- Hibernate的DAO層開(kāi)發(fā)比MyBatis簡(jiǎn)單,Mybatis需要維護(hù)SQL和結(jié)果映射。
- Hibernate對(duì)對(duì)象的維護(hù)和緩存要比MyBatis好,對(duì)增刪改查的對(duì)象的維護(hù)要方便。
- Hibernate數(shù)據(jù)庫(kù)移植性很好,MyBatis的數(shù)據(jù)庫(kù)移植性不好,不同的數(shù)據(jù)庫(kù)需要寫(xiě)不同SQL。
- Hibernate有更好的二級(jí)緩存機(jī)制,可以使用第三方緩存。MyBatis本身提供的緩存機(jī)制不佳。
摘自某乎上的經(jīng)典總結(jié):
Hibernate
- Hibernate功能強(qiáng)大,數(shù)據(jù)庫(kù)無(wú)關(guān)性好,O/R映射能力強(qiáng),如果你對(duì)Hibernate相當(dāng)精通,而且對(duì)Hibernate進(jìn)行了適當(dāng)?shù)姆庋b,那么你的項(xiàng)目整個(gè)持久層代碼會(huì)相當(dāng)簡(jiǎn)單,需要寫(xiě)的代碼很少,開(kāi)發(fā)速度很快,非常爽。
- Hibernate的缺點(diǎn)就是學(xué)習(xí)門(mén)檻不低,要精通門(mén)檻更高,而且怎么設(shè)計(jì)O/R映射,在性能和對(duì)象模型之間如何權(quán)衡取得平衡,以及怎樣用好Hibernate方面需要你的經(jīng)驗(yàn)和能力都很強(qiáng)才行。
MyBatis
- MyBatis入門(mén)簡(jiǎn)單,即學(xué)即用,提供了數(shù)據(jù)庫(kù)查詢(xún)的自動(dòng)對(duì)象綁定功能,而且延續(xù)了很好的SQL使用經(jīng)驗(yàn),對(duì)于沒(méi)有那么高的對(duì)象模型要求的項(xiàng)目來(lái)說(shuō),相當(dāng)完美。
- MyBatis的缺點(diǎn)就是框架還是比較簡(jiǎn)陋,功能尚有缺失,雖然簡(jiǎn)化了數(shù)據(jù)綁定代碼,但是整個(gè)底層數(shù)據(jù)庫(kù)查詢(xún)實(shí)際還是要自己寫(xiě)的,工作量也比較大,而且不太容易適應(yīng)快速數(shù)據(jù)庫(kù)修改。 深入追問(wèn): 追問(wèn)1:Hibernate與Mybatis 的緩存機(jī)制都有哪些區(qū)別?
相同點(diǎn):
Hibernate和Mybatis的二級(jí)緩存除了采用系統(tǒng)默認(rèn)的緩存機(jī)制外,都可以通過(guò)實(shí)現(xiàn)你自己的緩存或?yàn)槠渌谌骄彺娣桨?,?chuàng)建適配器來(lái)完全覆蓋緩存行為。
不同點(diǎn):
Hibernate的二級(jí)緩存配置在SessionFactory生成的配置文件中進(jìn)行詳細(xì)配置,然后再在具體的表-對(duì)象映射中配置是那種緩存。
MyBatis的二級(jí)緩存配置都是在每個(gè)具體的表-對(duì)象映射中進(jìn)行詳細(xì)配置,這樣針對(duì)不同的表可以自定義不同的緩存機(jī)制。并且Mybatis可以在命名空間中共享相同的緩存配置和實(shí)例,通過(guò)Cache-ref來(lái)實(shí)現(xiàn)。
兩者比較: 因?yàn)镠ibernate對(duì)查詢(xún)對(duì)象有著良好的管理機(jī)制,用戶(hù)無(wú)需關(guān)心SQL。所以在使用二級(jí)緩存時(shí)如果出現(xiàn)臟數(shù)據(jù),系統(tǒng)會(huì)報(bào)出錯(cuò)誤并提示。
而MyBatis在這一方面,使用二級(jí)緩存時(shí)需要特別小心。如果不能完全確定數(shù)據(jù)更新操作的波及范圍,避免Cache的盲目使用。否則,臟數(shù)據(jù)的出現(xiàn)會(huì)給系統(tǒng)的正常運(yùn)行帶來(lái)很大的隱患。
面試題3:Mybatis中的#{}和${}有哪些區(qū)別
正經(jīng)回答:
-- #{} <select id="userLogin" parameterType="java.util.Map" resultMap="userResMap"> select id, username, password, role from user where username = #{username} and password = #{password} </select> -- ${} <select id="userLogin" parameterType="java.util.Map" resultMap="userResMap"> select id, username, password, role from user where username = ${username} and password = ${password} </select>
1.#將傳入的數(shù)據(jù)都當(dāng)成一個(gè)字符串,會(huì)對(duì)自動(dòng)傳入的數(shù)據(jù)加一個(gè)雙引號(hào)。
如:where username=#{username},
如果傳入的值是111,那么解析成sql時(shí)的值為where username=“111”, 如果傳入的值是id,則解析成的sql為where username=“id”.
2.$將傳入的數(shù)據(jù)直接顯示生成在sql中。
如:where username=${username},
如果傳入的值是111,那么解析成sql時(shí)的值為where username=111;
那么,如果傳入的值是:;drop table user
;會(huì)怎么樣?解析后的sql為:
select id, username, password, role from user where username=;drop table user;
#方式能夠很大程度防止sql注入,$方式無(wú)法防止Sql注入。
$方式一般用于傳入數(shù)據(jù)庫(kù)對(duì)象,例如傳入表名;
一般能用#的就別用$
,若不得不使用 “${xxx}”
這樣的參數(shù),要手工地做好過(guò)濾工作,來(lái)防止sql注入攻擊。
在MyBatis中,“${xxx}”
這樣格式的參數(shù)會(huì)直接參與SQL編譯,從而不能避免注入攻擊。但涉及到動(dòng)態(tài)表名和列名時(shí),只能使用“${xxx}”
這樣的參數(shù)格式。所以,這樣的參數(shù)需要我們?cè)诖a中手工進(jìn)行處理來(lái)防止注入。
綜上,我們?cè)诰帉?xiě)MyBatis的映射語(yǔ)句時(shí),盡量采用“#{xxx}”
這樣的格式。若不得不使用“${xxx}”
這樣的參數(shù),要手工地做好過(guò)濾工作,來(lái)防止SQL注入攻擊。
深入追問(wèn):
追問(wèn)1:什么是sql注入?
sql注入是一種代碼注入技術(shù),用于攻擊數(shù)據(jù)驅(qū)動(dòng)的應(yīng)用,惡意的SQL語(yǔ)句被插入到執(zhí)行的實(shí)體字段中(例如,為了轉(zhuǎn)儲(chǔ)數(shù)據(jù)庫(kù)內(nèi)容給攻擊者)
說(shuō)到SQL注入,相信大家都不陌生,這是黑客同學(xué)常用的一種攻擊方式。攻擊者在界面的表單信息或URL上輸入一些奇怪的SQL片段(例如“or ‘1'='1'
”這樣的語(yǔ)句),有可能入侵參數(shù)檢驗(yàn)不足的應(yīng)用程序。
所以,在我們的應(yīng)用中需要做一些工作,來(lái)防備這樣的攻擊方式。在一些安全性要求很高的應(yīng)用中(比如銀行軟件),經(jīng)常使用將SQL語(yǔ)句全部替換為存儲(chǔ)過(guò)程這樣的方式,來(lái)防止SQL注入。這當(dāng)然是一種很安全的方式,但我們平時(shí)開(kāi)發(fā)中,可能不需要這種死板的方式。
追問(wèn)2:mybatis是如何做到防止sql注入的?
MyBatis框架作為一款半自動(dòng)化的持久層框架,其SQL語(yǔ)句都要我們自己手動(dòng)編寫(xiě),這個(gè)時(shí)候當(dāng)然需要防止SQL注入。其實(shí),MyBatis的SQL是一個(gè)具有“輸入+輸出”的功能,類(lèi)似于函數(shù)的結(jié)構(gòu),參考上面的兩個(gè)例子。
其中,parameterType表示了輸入的參數(shù)類(lèi)型,resultType表示了輸出的參數(shù)類(lèi)型?;貞?yīng)上文,如果我們想防止SQL注入,理所當(dāng)然地要在輸入?yún)?shù)上下功夫。上面代碼中使用#的即輸入?yún)?shù)在SQL中拼接的部分,傳入?yún)?shù)后,打印出執(zhí)行的SQL語(yǔ)句,會(huì)看到SQL是這樣的:
select id, username, password, role from user where username=? and password=?
不管輸入什么參數(shù),打印出的SQL都是這樣的。這是因?yàn)镸yBatis啟用了預(yù)編譯功能,在SQL執(zhí)行前,會(huì)先將上面的SQL發(fā)送給數(shù)據(jù)庫(kù)進(jìn)行編譯;執(zhí)行時(shí),直接使用編譯好的SQL,替換占位符“?”就可以了。因?yàn)镾QL注入只能對(duì)編譯過(guò)程起作用,所以這樣的方式就很好地避免了SQL注入的問(wèn)題。
總結(jié)
本篇文章就到這里了,希望能給你帶來(lái)幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
java+sqlserver實(shí)現(xiàn)學(xué)生信息管理系統(tǒng)
這篇文章主要介紹了利用java和sqlserver實(shí)現(xiàn)學(xué)生信息管理系統(tǒng),違章內(nèi)容主要建立了與sqlserver數(shù)據(jù)庫(kù)的連接開(kāi)始展開(kāi)內(nèi)容,能學(xué)到了解JDBC執(zhí)行SQL的語(yǔ)法,需要的朋友可以參考一下2021-12-12SpringBoot異常錯(cuò)誤頁(yè)面實(shí)現(xiàn)方法介紹
在項(xiàng)目訪(fǎng)問(wèn)的時(shí)候我們經(jīng)常會(huì)發(fā)生錯(cuò)誤或者頁(yè)面找不到,比如:資源找不到404,服務(wù)器500錯(cuò)誤,默認(rèn)情況下springboot的處理機(jī)制都是去跳轉(zhuǎn)內(nèi)部的錯(cuò)誤地址:/error 和與之對(duì)應(yīng)的一個(gè)錯(cuò)誤頁(yè)面2022-09-09java 日志的數(shù)據(jù)脫敏的實(shí)現(xiàn)方法
今日給大家介紹一下java 日志的數(shù)據(jù)脫敏的實(shí)現(xiàn)方法,可以更好的保護(hù)數(shù)據(jù)的安全,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-01-01springboot+mybaties項(xiàng)目中掃描不到@mapper注解的解決方法
本文主要介紹了springboot+mybaties項(xiàng)目中掃描不到@mapper注解的解決方法,該報(bào)錯(cuò)表明掃描不到Mapper層,具有一定的參考價(jià)值,感興趣的可以了解一下2024-05-05MyEclipse開(kāi)發(fā)一個(gè)webservice接口
這篇文章主要為大家詳細(xì)介紹了MyEclipse開(kāi)發(fā)一個(gè)webservice接口,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-07-07淺談java中的一維數(shù)組、二維數(shù)組、三維數(shù)組、多維數(shù)組
下面小編就為大家?guī)?lái)一篇淺談java中的一維數(shù)組、二維數(shù)組、三維數(shù)組、多維數(shù)組。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-05-05