1. #{}和${}的區(qū)別是什么戈擒?
其中#{}是預(yù)編譯處理,{}時柑船,就是把{column}
傳同樣的column值id,上面的語句會解析成 order by 'id'鞍时,下面的語句會解析成order by id,如果要做動態(tài)sql的話,就可以使用${}扣蜻。
使用#{}可以有效的防止SQL注入逆巍,提高系統(tǒng)安全性。
2. Mybatis是如何進(jìn)行分頁的莽使?分頁插件的原理是什么锐极?
Mybatis可以使用RowBounds對象來進(jìn)行分頁,通過ResultSet結(jié)果集來執(zhí)行的內(nèi)存分頁芳肌,并不是一般來說的物理分頁灵再,可以在sql語句里面直接添加帶有物理分頁的參數(shù)來完成物理分頁功能,也可以使用分頁插件來完成物理分頁亿笤,比如PageHelper檬嘀。
分頁插件的基本原理:通過使用Mybatis提供的插件接口,來實(shí)現(xiàn)自定義分頁责嚷,在插件自帶的攔截方法里攔截待執(zhí)行的sql(也就啊hi我們查詢的需要分頁的內(nèi)容),然后重寫sql掂铐,根據(jù)dialect方法添加對應(yīng)的分頁語句和分頁參數(shù)罕拂。
3. Mybatis是如何將sql執(zhí)行結(jié)果封裝為目標(biāo)對象并返回的揍异?都有哪些映射形式?
有兩種映射關(guān)系
第一種是使用<resultMap>標(biāo)簽爆班,定義多個列名和對象屬性名之間的映射關(guān)系衷掷。
第二種是使用sql列的列別名功能,將列別名書寫為對象屬性名柿菩,比如T_ID AS ID戚嗅,對象屬性名一般是id,小寫枢舶,但是列名不區(qū)分大小寫懦胞,Mybatis會忽略列名大小寫,智能找到與之對應(yīng)對象屬性名凉泄。
有了列名與屬性名的映射關(guān)系后躏尉,Mybatis通過反射創(chuàng)建對象,同時使用反射給對象的屬性逐一賦值并返回后众,如果映射關(guān)系對應(yīng)不上就無法完成復(fù)制胀糜。
4. 通常一個Xml映射文件,都會寫一個Dao接口與之對應(yīng)蒂誉,請問教藻,這個Dao接口的工作原理是什么?Dao接口里的方法右锨,參數(shù)不同時括堤,方法能重載嗎?
Dao接口陡蝇,也就是人們常說的Mapper接口痊臭,接口的全限名,就是映射文件中的namespace的值登夫,接口的方法名广匙,就是映射文件中MappedStatement的id值,接口方法內(nèi)的參數(shù)恼策,就是傳遞給sql的參數(shù)鸦致。Mapper接口是沒有實(shí)現(xiàn)類的,當(dāng)調(diào)用接口方法時涣楷,接口全限名+方法名拼接字符串作為key值分唾,可唯一定位一個MappedStatement,舉例:com.mybatis3.mappers.StudentDao.findStudentById狮斗,可以唯一找到namespace為com.mybatis3.mappers.StudentDao下面id = findStudentById的MappedStatement绽乔。在Mybatis中,每一個<select>碳褒、<insert>折砸、<update>看疗、<delete>標(biāo)簽,都會被解析為一個MappedStatement對象睦授。
Dao接口里的方法两芳,是不能重載的,因?yàn)槭侨廾?方法名的保存和尋找策略去枷。
Dao接口的工作原理是JDK動態(tài)代理怖辆,Mybatis運(yùn)行時會使用JDK動態(tài)代理為Dao接口生成代理proxy對象,代理對象proxy會攔截接口方法删顶,轉(zhuǎn)而執(zhí)行MappedStatement所代表的sql竖螃,然后將sql執(zhí)行結(jié)果返回。
5. Xml映射文件中翼闹,除了常見的select|insert|update|delete標(biāo)簽之外斑鼻,還有哪些標(biāo)簽?
其實(shí)除了這些常見標(biāo)簽猎荠,還有很多其他的標(biāo)簽坚弱,加上動態(tài)sql的9個標(biāo)簽:if、choose关摇、when荒叶、otherwise、trim输虱、where些楣、set、foreach宪睹、bind等愁茁,其中為sql片段標(biāo)簽,通過標(biāo)簽引入sql片段亭病,可以為不支持自增的主鍵生成策略標(biāo)簽鹅很。
6. 簡述Mybatis的插件運(yùn)行原理,以及如何編寫一個插件
Mybatis只能編寫針對ParameterHandler罪帖、ResultSetHandler促煮、StatementHandler、Executor這4種接口的插件整袁。Mybatis使用JDK的動態(tài)代理菠齿,來為我們需要攔截的接口生成代理對象,以及實(shí)現(xiàn)接口方法的攔截功能每次執(zhí)行這些方法的時候坐昙,就會直接進(jìn)入攔截方法绳匀,具體方式是InvocationHandler的invoke()方法。這個方法只會攔截指定的需要攔截的方法。
自定義插件:實(shí)現(xiàn)Mybatis的Interceptor接口并復(fù)寫intercept()方法襟士,給插件編寫注解盗飒,指定要攔截接口的一個或多個方法,最后還需要在配置文件中配置編寫的插件陋桂。
7. 一級、二級緩存
一級緩存是基于 PerpetualCache 的 HashMap 本地緩存蝶溶,存儲作用域?yàn)?Session嗜历,當(dāng) Session flush 或 close 之后,該 Session 中的所有 Cache 就將清空抖所。
二級緩存與一級緩存其機(jī)制相同梨州,默認(rèn)也是采用 PerpetualCache的HashMap 存儲,不同的地方就是存儲作用域改為 Mapper(Namespace)田轧,而且可以自定義存儲源暴匠,如 Ehcache。要使用二級緩存傻粘,需要在 SQL 映射文件中添加一行:<cache/>
8. Mybatis是否支持延遲加載每窖?如果支持,它的實(shí)現(xiàn)原理是什么弦悉?
Mybatis支持部分的延遲加載窒典,它僅支持association關(guān)聯(lián)對象和collection關(guān)聯(lián)集合對象的延遲加載。
association指的就是一對一稽莉,collection指的就是一對多查詢瀑志。
在Mybatis配置文件中,可以配置是否啟用延遲加載lazyLoadingEnabled=true|false污秆。
實(shí)現(xiàn)原理:使用CGLIB創(chuàng)建目標(biāo)對象的代理對象劈猪,當(dāng)調(diào)用目標(biāo)方法時,進(jìn)入攔截器方法良拼。比如調(diào)用aaa.getB().getName()战得,如果aaa.getB()的值為空,攔截器invoke()方法發(fā)現(xiàn)aaa.getB()是null值将饺,就會單獨(dú)發(fā)送事先保存好的查詢關(guān)聯(lián)B對象的sql贡避,把B查詢上來,然后再來調(diào)用aaa.setB(b)予弧,這時aaa對象的b屬性就有值了刮吧,就可以繼續(xù)方法的調(diào)用,獲取name掖蛤,接著完成a.getB().getName()方法的調(diào)用杀捻。
9. Mybatis映射文件中,如果A標(biāo)簽通過include引用了B標(biāo)簽的內(nèi)容蚓庭,請問致讥,B標(biāo)簽?zāi)芊穸x在A標(biāo)簽的后面仅仆,還是說必須定義在A標(biāo)簽的前面?
雖然Mybatis解析Xml映射文件是按照順序解析的垢袱,但是墓拜,被引用的B標(biāo)簽依然可以定義在任何地方,Mybatis都能夠正確識別请契。
原理:Mybatis解析A標(biāo)簽時咳榜,發(fā)現(xiàn)A標(biāo)簽引用了B標(biāo)簽,但是B標(biāo)簽還沒有解析到爽锥,不存在涌韩,這時,Mybatis會將A標(biāo)簽標(biāo)記為未解析狀態(tài)氯夷,然后繼續(xù)解析余下的標(biāo)簽臣樱,這里面也就包含B標(biāo)簽。當(dāng)所有標(biāo)簽按順序解析完畢時腮考,Mybatis又會重新開始解析那些被標(biāo)記為未解析狀態(tài)的標(biāo)簽雇毫,這是再解析A標(biāo)簽時,B標(biāo)簽已經(jīng)存在秸仙,A標(biāo)簽也就可以正常解析完成了嘴拢。
10. 簡述Mybatis的Xml映射文件和Mybatis內(nèi)部數(shù)據(jù)結(jié)構(gòu)之間的映射關(guān)系?
Mybatis是將所有的Xml配置信息都封裝到一個All-In-One重量級對象的Configuration內(nèi)部寂纪。
在Xml映射文件中席吴,<parameterMap>標(biāo)簽會被解析為ParameterMap對象,然后每個子元素會被解析為ParameterMapping對象捞蛋。
<resultMap>標(biāo)簽會被解析為ResultMap對象孝冒,然后每個子元素也會被解析為ResultMapping對象。
每一個<insert>拟杉、<delete>庄涡、<update>、<select>標(biāo)簽都會被解析為MappedStatement對象搬设,標(biāo)簽內(nèi)的sql會被解析為BoundSql對象穴店。