1.#{}和${}的區(qū)別是什么?
#{}是預編譯處理,${}是字符串替換,
Mybatis在處理#{}時室埋,在SQL執(zhí)行之前弧圆,將SQL發(fā)送給數(shù)據(jù)庫進行編譯,會將sql中的#{}替換為?號,在執(zhí)行時調(diào)用PreparedStatement的set方法來賦值;
Mybatis在處理 ${} 時,就是把${}替換成變量的值,直接進行sql拼接坷牛。
使用#{}可以有效的防止SQL注入,提高系統(tǒng)安全性很澄。
2.當實體類中的屬性名和表中的字段名不一樣 京闰,怎么辦 颜及?
(1)修改數(shù)據(jù)庫中的字段名
(2)通過<resultMap>來映射字段名和實體類屬性名的一一對應關系
3.模糊查詢like語句該怎么寫?
(1)在Java代碼中添加sql通配符。
(2)在sql語句中拼接通配符蹂楣,會引起sql注入
4.通常一個Xml映射文件俏站,都會寫一個Dao接口與之對應,請問痊土,這個Dao接口的工作原理是什么肄扎?Dao接口里的方法,參數(shù)不同時赁酝,方法能重載嗎犯祠?
- Dao接口,就是人們常說的Mapper接口酌呆,接口的全限名衡载,就是映射文件中的namespace的值,接口的方法名隙袁,就是映射文件中MappedStatement的id值痰娱,接口方法內(nèi)的參數(shù),就是傳遞給sql的參數(shù)菩收。Mapper接口是沒有實現(xiàn)類的梨睁,當調(diào)用接口方法時,接口全限名+方法名拼接字符串作為key值娜饵,可唯一定位一個MappedStatement坡贺。
- Dao接口里的方法,是不能重載的箱舞,因為是全限名+方法名的保存和尋找策略拴念。
- Dao接口的工作原理是JDK動態(tài)代理,Mybatis運行時會使用JDK動態(tài)代理為Dao接口生成代理proxy對象褐缠,代理對象proxy會攔截接口方法,轉而執(zhí)行MappedStatement所代表的sql风瘦,然后將sql執(zhí)行結果返回队魏。
5.Mybatis是如何將sql執(zhí)行結果封裝為目標對象并返回的?都有哪些映射形式万搔?
- 第一種是使用<resultMap>標簽胡桨,逐一定義列名和對象屬性名之間的映射關系。
- 第二種是使用sql列的別名功能瞬雹,將列別名書寫為對象屬性名昧谊,比如 T_NAME AS NAME,對象屬性名一般是name酗捌,小寫呢诬,但是列名不區(qū)分大小寫涌哲,Mybatis會忽略列名大小寫,智能找到與之對應對象屬性名尚镰,你甚至可以寫成T_NAME AS NaMe阀圾,Mybatis一樣可以正常工作。有了列名與屬性名的映射關系后狗唉,Mybatis通過反射創(chuàng)建對象初烘,同時使用反射給對象的屬性逐一賦值并返回,那些找不到映射關系的屬性分俯,是無法完成賦值的肾筐。
6.如何獲取自動生成的(主)鍵值?
insert 方法總是返回一個int值 - 這個值代表的是插入的行數(shù)。
通過屬性usegeneratedkeys=””和keyproperty=””來獲取生成的鍵值缸剪,自動生成的鍵值被傳入的參數(shù)對象中吗铐。
7.Mybatis動態(tài)sql是做什么的?都有哪些動態(tài)sql橄登?能簡述一下動態(tài)sql的執(zhí)行原理不抓歼?
Mybatis動態(tài)sql可以讓我們在Xml映射文件內(nèi),以標簽的形式編寫動態(tài)sql拢锹,完成邏輯判斷和動態(tài)拼接sql的功能谣妻。
Mybatis提供了9種動態(tài)sql標簽:trim|where|set|foreach|if|choose|when|otherwise|bind。
其執(zhí)行原理為卒稳,使用OGNL從sql參數(shù)對象中計算表達式的值蹋半,根據(jù)表達式的值動態(tài)拼接sql,以此來完成動態(tài)sql的功能充坑。
8.Mybatis的Xml映射文件中减江,不同的Xml映射文件,id是否可以重復捻爷?
不同的Xml映射文件辈灼,如果配置了namespace,那么id可以重復也榄;如果沒有配置namespace巡莹,那么id不能重復;畢竟namespace不是必須的甜紫,只是最佳實踐而已降宅。
9.為什么說Mybatis是半自動ORM映射工具?它與全自動的區(qū)別在哪里囚霸?
Hibernate屬于全自動ORM映射工具腰根,使用Hibernate查詢關聯(lián)對象或者關聯(lián)集合對象時,可以根據(jù)對象關系模型直接獲取拓型,所以它是全自動的额嘿。而Mybatis在查詢關聯(lián)對象或關聯(lián)集合對象時瘸恼,需要手動編寫sql來完成,所以岩睁,稱之為半自動ORM映射工具钞脂。
10.Mybatis的一級、二級緩存:
1)一級緩存: 基于 PerpetualCache 的 HashMap 本地緩存捕儒,其存儲作用域為 Session冰啃,當 Session flush 或 close 之后,該 Session 中的所有 Cache 就將清空刘莹,默認打開一級緩存阎毅。
2)二級緩存與一級緩存其機制相同,默認也是采用 PerpetualCache点弯,HashMap 存儲扇调,不同在于其存儲作用域為 Mapper(Namespace),并且可自定義存儲源抢肛,如 Ehcache狼钮。默認不打開二級緩存,要開啟二級緩存捡絮,使用二級緩存屬性類需要實現(xiàn)Serializable序列化接口(可用來保存對象的狀態(tài)),可在它的映射文件中配置<cache/> 熬芜;
3)對于緩存數(shù)據(jù)更新機制,當某一個作用域(一級緩存 Session/二級緩存Namespaces)的進行了C/U/D 操作后福稳,默認該作用域下所有 select 中的緩存將被 clear涎拉。
11.什么是MyBatis的接口綁定,有什么好處?
接口映射就是在MyBatis中任意定義接口,然后把接口里面的方法和SQL語句綁定, 我們直接調(diào)用接口方法就可以,這樣比起原來了SqlSession提供的方法我們可以有更加靈活的選擇和設置.
12.接口綁定有幾種實現(xiàn)方式,分別是怎么實現(xiàn)的的圆?
接口綁定有兩種實現(xiàn)方式,一種是通過注解綁定,就是在接口的方法上面加上 @Select鼓拧、@Update等注解,里面包含Sql語句來綁定越妈;另外一種就是通過xml里面寫SQL來綁定, 在這種情況下,要指定xml映射文件里面的namespace必須為接口的全路徑名.
13.什么情況下用注解綁定,什么情況下用xml綁定 季俩?
當Sql語句比較簡單時候,用注解綁定, 當SQL語句比較復雜時候,用xml綁定,一般用xml綁定的比較多。
14.Mybatis分層結構
15.Mybatis都有哪些Executor執(zhí)行器梅掠?它們之間的區(qū)別是什么种玛?
Mybatis有三種基本的Executor執(zhí)行器,SimpleExecutor瓤檐、ReuseExecutor、BatchExecutor娱节。
SimpleExecutor:每執(zhí)行一次update或select挠蛉,就開啟一個Statement對象,用完立刻關閉Statement對象肄满。
ReuseExecutor:執(zhí)行update或select谴古,以sql作為key查找Statement對象质涛,存在就使用,不存在就創(chuàng)建掰担,用完后汇陆,不關閉Statement對象,而是放置于Map<String, Statement>內(nèi)带饱,供下一次使用毡代。簡言之,就是重復使用Statement對象勺疼。
BatchExecutor:執(zhí)行update(沒有select教寂,JDBC批處理不支持select),將所有sql都添加到批處理中(addBatch())执庐,等待統(tǒng)一執(zhí)行(executeBatch())酪耕,它緩存了多個Statement對象,每個Statement對象都是addBatch()完畢后轨淌,等待逐一執(zhí)行executeBatch()批處理迂烁。與JDBC批處理相同。
作用范圍:Executor的這些特點递鹉,都嚴格限制在SqlSession生命周期范圍內(nèi)
16.Mybatis中如何指定使用哪一種Executor執(zhí)行器盟步?
在Mybatis配置文件中,可以指定默認的ExecutorType執(zhí)行器類型梳虽,也可以手動給DefaultSqlSessionFactory的創(chuàng)建SqlSession的方法傳遞ExecutorType類型參數(shù)址芯。
17.Mybatis映射文件中,如果A標簽通過include引用了B標簽的內(nèi)容窜觉,請問谷炸,B標簽能否定義在A標簽的后面,還是說必須定義在A標簽的前面禀挫?
雖然Mybatis解析Xml映射文件是按照順序解析的旬陡,但是,被引用的B標簽依然可以定義在任何地方语婴,Mybatis都可以正確識別描孟。
原理是,Mybatis解析A標簽砰左,發(fā)現(xiàn)A標簽引用了B標簽匿醒,但是B標簽尚未解析到,尚不存在缠导,此時廉羔,Mybatis會將A標簽標記為未解析狀態(tài),然后繼續(xù)解析余下的標簽僻造,包含B標簽憋他,待所有標簽解析完畢孩饼,Mybatis會重新解析那些被標記為未解析的標簽,此時再解析A標簽時竹挡,B標簽已經(jīng)存在镀娶,A標簽也就可以正常解析完成了。
18.使用MyBatis的mapper接口調(diào)用有哪些要求揪罕?
(1)Mapper接口方法名和mapper.xml中定義的每個sql的id相同
(2)Mapper接口中輸入的參數(shù)類型和mapper.xml中定義的每個sql的ParameterType相同
(3)Mapper接口中輸出的參數(shù)類型和mapper.xml中定義的每個sql的resultType相同
(4)Mapper.xml文件中的namespace即是接口的類路徑
19.Statement和PrepareStatement的區(qū)別
PreparedStatement:表示預編譯的 SQL 語句的對象梯码。
(1)PrepareStatement可以使用占位符,是預編譯的耸序,批處理比Statement效率高
(2)在對數(shù)據(jù)庫只執(zhí)行一次性存取的時侯忍些,用 Statement 對象進行處理。
(3)PreparedStatement的第一次執(zhí)行消耗是很高的. 它的性能體現(xiàn)在后面的重復執(zhí)行