1. 程式人生 > >mybatis面試題總結大全

mybatis面試題總結大全

1.介面繫結有幾種實現方式,分別是怎麼實現的?
介面繫結有兩種實現方式,一種是通過註解繫結,就是在介面的方法上面加上 @[email protected]等註解裡面包含Sql語句來繫結,
另外一種就是通過xml裡面寫SQL來繫結, 在這種情況下,要指定xml對映檔案裡面的namespace必須為介面的全路徑名.

2什麼情況下用註解繫結,什麼情況下用xml繫結?
當Sql語句比較簡單時候,用註解繫結,
當SQL語句比較複雜時候,用xml繫結,一般用xml繫結的比較多

3.MyBatis實現一對多有幾種方式,怎麼操作的?
有聯合查詢和巢狀查詢,聯合查詢是幾個表聯合查詢,只查詢一次,通過在resultMap裡面配 置collection節點配置一對多的類就可以完成;
巢狀查詢是先查一個表,根據這個表裡面的 結果的外來鍵id,去再另外一個表裡面查詢資料,也是通過配置collection,但另外一個表的 查詢通過select節點配置。
樣例:

https://www.cnblogs.com/xdp-gacl/p/4264440.html

4.MyBatis裡面的動態Sql是怎麼設定的?用什麼語法?
MyBatis裡面的動態Sql一般是通過if節點來實現,通過OGNL語法來實現,但是如果要寫的完 整,必須配合where,trim節點,where節點是判斷包含節點有內容就插入where,否則不插 入,trim節點是用來判斷如果動態語句是以and 或or開始,那麼會自動把這個and或者or取 掉

5.講下MyBatis的快取
MyBatis的快取分為一級快取和二級快取, 一級快取放在session裡面,預設就有,二級快取放在它的名稱空間裡,預設是開啟的, 使用二級快取屬性類需要實現Serializable序列化接 口(可用來儲存物件的狀態),可在它的對映檔案中配置
關於快取,可以參考:

http://blog.csdn.net/zouxucong/article/details/68947052
引申,為何用redis做mybatis二級快取:http://ask.csdn.net/questions/385019

6.MyBatis(IBatis)的好處是什麼
ibatis把sql語句從Java源程式中獨立出來, 放在單獨的XML檔案中編寫,給程式的維護帶來了很大便利。 ibatis封裝了底層JDBC API的呼叫細節,並能自動將結果集轉換成Java Bean物件, 大大簡化了Java資料庫程式設計的重複工作。 因為Ibatis需要程式設計師自己去編寫sql語句, 程式設計師可以結合資料庫自身的特點靈活控制sql語句, 因此能夠實現比hibernate等全自動orm框架更高的查詢效率,能夠完成複雜查詢.

7.Mybatis基礎: #{…} 和 {…} 的區別  
MyBatis將 #{…} 解釋為JDBC prepared statement 的一個引數標記。而將
{…} 解釋為字串替換。理解這兩者的區別是很有用的, 因為在某些SQL語句中並不能使用引數標記(parameter markers)。
“#{}”可以防止sql注入攻擊,因為會將傳入的資料加上”“。

8、如何執行批量插入?
首先,建立一個簡單的insert語句:
01.
02. insert into names (name) values (#{value})
03.
然後在Java程式碼中像下面這樣執行批處理插入:
01.List names = new ArrayList();
02.names.add(“Fred”);
03.names.add(“Barney”);
04.names.add(“Betty”);
05.names.add(“Wilma”);
06.
07.// 注意這裡 ExecutorType.BATCH
08.SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
09.try {
10. NameMapper mapper = sqlSession.getMapper(NameMapper.class);
11. for (String name : names) {
12. mapper.insertName(name);
13. }
14. sqlSession.commit();
15.} finally {
16. sqlSession.close();
17.}
ssm框架可以在xml中利用標籤實現批量插入

9、如何獲取自動生成的(主)鍵值?
insert 方法總是返回一個int值 - 這個值代表的是插入的行數。而自動生成的鍵值在 insert 方法執行完後可以被設定到傳入的引數物件中。
示例:
01.
02. insert into names (name) values (#{name})
03.

10、Xml對映檔案中,除了常見的select|insert|updae|delete標籤之外,還有哪些標籤?
答:還有很多其他的標籤,、、、、,加上動態sql的9個標籤,trim|where|set|foreach|if|choose|when|otherwise|bind等,其中為sql片段標籤,通過標籤引入sql片段,為不支援自增的主鍵生成策略標籤。

11、最佳實踐中,通常一個Xml對映檔案,都會寫一個Dao介面與之對應,請問,這個Dao介面的工作原理是什麼?Dao接口裡的方法,引數不同時,方法能過載嗎?
答:Dao介面,就是人們常說的Mapper介面,介面的全限名,就是對映檔案中的namespace的值,介面的方法名,就是對映檔案中MappedStatement的id值,介面方法內的引數,就是傳遞給sql的引數。Mapper介面是沒有實現類的,當呼叫介面方法時,介面全限名+方法名拼接字串作為key值,可唯一定位一個MappedStatement,舉例:com.mybatis3.mappers.StudentDao.findStudentById,可以唯一找到namespace為com.mybatis3.mappers.StudentDao下面id = findStudentById的MappedStatement。在Mybatis中,每一個、、、標籤,都會被解析為一個MappedStatement物件。
Dao接口裡的方法,是不能過載的,因為是全限名+方法名的儲存和尋找策略。
Dao介面的工作原理是JDK動態代理,Mybatis執行時會使用JDK動態代理為Dao介面生成代理proxy物件,代理物件proxy會攔截介面方法,轉而執行MappedStatement所代表的sql,然後將sql執行結果返回。

12、Mybatis是如何進行分頁的?分頁外掛的原理是什麼?
答:Mybatis使用RowBounds物件進行分頁,它是針對ResultSet結果集執行的記憶體分頁,而非物理分頁,可以在sql內直接書寫帶有物理分頁的引數來完成物理分頁功能,也可以使用分頁外掛來完成物理分頁。

分頁外掛的基本原理是使用Mybatis提供的外掛介面,實現自定義外掛,在外掛的攔截方法內攔截待執行的sql,然後重寫sql,根據dialect方言,新增對應的物理分頁語句和物理分頁引數。

13、簡述Mybatis的外掛執行原理,以及如何編寫一個外掛。

答:Mybatis僅可以編寫針對ParameterHandler、ResultSetHandler、StatementHandler、Executor這4種介面的外掛,Mybatis使用JDK的動態代理,為需要攔截的介面生成代理物件以實現介面方法攔截功能,每當執行這4種介面物件的方法時,就會進入攔截方法,具體就是InvocationHandler的invoke()方法,當然,只會攔截那些你指定需要攔截的方法。
實現Mybatis的Interceptor介面並複寫intercept()方法,然後在給外掛編寫註解,指定要攔截哪一個介面的哪些方法即可,記住,別忘了在配置檔案中配置你編寫的外掛。

14、Mybatis動態sql是做什麼的?都有哪些動態sql?能簡述一下動態sql的執行原理不?
答:Mybatis動態sql可以讓我們在Xml對映檔案內,以標籤的形式編寫動態sql,完成邏輯判斷和動態拼接sql的功能,Mybatis提供了9種動態sql標籤trim|where|set|foreach|if|choose|when|otherwise|bind。
其執行原理為,使用OGNL從sql引數物件中計算表示式的值,根據表示式的值動態拼接sql,以此來完成動態sql的功能。

15、Mybatis是如何將sql執行結果封裝為目標物件並返回的?都有哪些對映形式?
答:第一種是使用標籤,逐一定義列名和物件屬性名之間的對映關係。第二種是使用sql列的別名功能,將列別名書寫為物件屬性名,比如T_NAME AS NAME,物件屬性名一般是name,小寫,但是列名不區分大小寫,Mybatis會忽略列名大小寫,智慧找到與之對應物件屬性名,你甚至可以寫成T_NAME AS NaMe,Mybatis一樣可以正常工作。
有了列名與屬性名的對映關係後,Mybatis通過反射建立物件,同時使用反射給物件的屬性逐一賦值並返回,那些找不到對映關係的屬性,是無法完成賦值的。

9、Mybatis一對多的關聯查詢都有哪些實現方式,以及它們之間的區別
答:關聯物件查詢,有兩種實現方式,一種是單獨傳送一個sql去查詢關聯物件,賦給主物件,然後返回主物件。另一種是使用巢狀查詢,巢狀查詢的含義為使用join查詢,一部分列是A物件的屬性值,另外一部分列是關聯物件B的屬性值,好處是隻發一個sql查詢,就可以把主物件和其關聯物件查出來。

那麼問題來了,join查詢出來100條記錄,如何確定主物件是5個,而不是100個?其去重複的原理是標籤內的子標籤,指定了唯一確定一條記錄的id列,Mybatis根據列值來完成100條記錄的去重複功能,可以有多個,代表了聯合主鍵的語意。

同樣主物件的關聯物件,也是根據這個原理去重複的,儘管一般情況下,只有主物件會有重複記錄,關聯物件一般不會重複。

舉例:下面join查詢出來6條記錄,一、二列是Teacher物件列,第三列為Student物件列,Mybatis去重複處理後,結果為1個老師6個學生,而不是6個老師6個學生。

   t_id    t_name           s_id

| 1 | teacher | 38 |
| 1 | teacher | 39 |
| 1 | teacher | 40 |
| 1 | teacher | 41 |
| 1 | teacher | 42 |
| 1 | teacher | 43 |

10、Mybatis是否支援延遲載入?如果支援,它的實現原理是什麼?
答:(延遲載入的好處及例項詳見:http://blog.csdn.net/eson_15/article/details/51668523
Mybatis僅支援association關聯物件和collection關聯集合物件的延遲載入,association指的就是一對一,collection指的就是一對多查詢。在Mybatis配置檔案中,可以配置是否啟用延遲載入lazyLoadingEnabled=true|false。

它的原理是,使用CGLIB建立目標物件的代理物件,當呼叫目標方法時,進入攔截器方法,比如呼叫a.getB().getName(),攔截器invoke()方法發現a.getB()是null值,那麼就會單獨傳送事先儲存好的查詢關聯B物件的sql,把B查詢上來,然後呼叫a.setB(b),於是a的物件b屬性就有值了,接著完成a.getB().getName()方法的呼叫。這就是延遲載入的基本原理。
當然了,不光是Mybatis,幾乎所有的包括Hibernate,支援延遲載入的原理都是一樣的。

11、Mybatis的Xml對映檔案中,不同的Xml對映檔案,id是否可以重複?
答:不同的xml對映檔案,如果配置了namespace,那麼id可以重複;如果沒有配置namespace,那麼id不能重複;畢竟namespace不是必須的,只是最佳實踐而已。
原因就是namespace+id是作為Map