1. 程式人生 > >mybaits面試題總結

mybaits面試題總結

1.#{}和${}的區別是什麼?

${}是變數佔位符,可以用於標籤屬性值和sql內部,屬於靜態文字替換。比如${driver}會被靜態替換為com.mysql.jdbc.Driver。

#{}是sql的引數佔位符,Mybatis會將sql中的#{}替換為?號

2、Xml對映檔案中,除了常見的select|insert|updae|delete標籤之外,還有哪些標籤?

<resultMap>、<parameterMap>、<sql>、<include>、<selectKey>

3、通常一個Xml對映檔案,都會寫一個Dao介面與之對應,請問,這個Dao介面的工作原理是什麼?Dao接口裡的方法,引數不同時,方法能過載嗎?

  Dao介面,就是人們常說的Mapper介面,

1.介面必須要和對映檔案同名且在同一個包下,也就是說對映檔案的namespace是介面的全類名。

2.介面中的方法必須和對映檔案定義的id相同。

3.介面中的方法輸入引數型別,返回型別都要和對映檔案中的parameterType和resultType一致。

Mapper介面是沒有實現類的,當呼叫介面方法時,介面全限名+方法名拼接字串作為key值,可唯一定位一個MappedStatement。

Dao接口裡的方法,是不能過載的,因為是全限名+方法名的儲存和尋找策略。

Dao介面的工作原理是JDK動態代理,Mybatis執行時會使用JDK動態代理為Dao介面生成代理proxy物件,代理物件proxy會攔截介面方法,轉而執行MappedStatement所代表的sql,然後將sql執行結果返回。

4.Mybatis是如何進行分頁的?分頁外掛的原理是什麼?

使用RowBounds物件進行分頁,針對Result結果集執行邏輯分頁,而非物理分頁。也可以在SQL中進行物理分頁,也可以用分頁外掛進行物理分頁。

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

5.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的功能。

6.Mybatis是如何將sql執行結果封裝為目標物件並返回的?都有哪些對映形式?

第一種是使用<resultMap>標籤,逐一定義列名和物件屬性名之間的對映關係。第二種是使用sql列的別名功能,將列別名書寫為物件屬性名。

7.Mybatis能執行一對一、一對多的關聯查詢嗎?都有哪些實現方式,以及它們之間的區別。

能。兩種:一種是單獨傳送一個sql去查詢關聯物件,賦給主物件,然後返回主物件。 <association property="user" javaType="User" resultMap="resultListUser" />  

另一種是使用巢狀查詢,ssociation property="user" javaType="User">

            <id property="id" colmn="id" />

            <result property="userName" column="userName" />

            <result property="userAddress" column="userAddress" />        

        </association> 

8.Mybatis是否支援延遲載入?如果支援,它的實現原理是什麼?

  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()方法的呼叫。這就是延遲載入的基本原理。

http://upload-images.jianshu.io/upload_images/4807654-fa19dc4b14682abd.PNG?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240

9. Mybatis的Xml對映檔案中,不同的Xml對映檔案,id是否可以重複?

不同的Xml對映檔案,如果配置了namespace,那麼id可以重複;如果沒有配置namespace,那麼id不能重複;畢竟namespace不是必須的,只是最佳實踐而已。原因就是namespace+id是作為Map<String, MappedStatement>的key使用的,如果沒有namespace,就剩下id,那麼,id重複會導致資料互相覆蓋。有了namespace,自然id就可以重複,namespace不同,namespace+id自然也就不同。

10. Mybatis都有哪些Executor執行器?它們之間的區別是什麼?

Mybatis有三種基本的Executor執行器,SimpleExecutor、ReuseExecutor、BatchExecutor。

SimpleExecutor每執行一次update或select,就開啟一個Statement物件,用完立刻關閉Statement物件。

ReuseExecutor執行update或select,以sql作為key查詢Statement物件,存在就使用,不存在就建立,用完後,不關閉Statement物件,而是放置於Map<String, Statement>內,供下一次使用。簡言之,就是重複使用Statement物件。

BatchExecutor執行update(沒有select,JDBC批處理不支援select),將所有sql都新增到批處理中(addBatch()),等待統一執行(executeBatch()),它快取了多個Statement物件,每個Statement物件都是addBatch()完畢後,等待逐一執行executeBatch()批處理。與JDBC批處理相同。

作用範圍:Executor的這些特點,都嚴格限制在SqlSession生命週期範圍內。

11.Mybatis中如何指定使用哪一種Executor執行器?

在Mybatis配置檔案中,可以指定預設的ExecutorType執行器型別,也可以手動給DefaultSqlSessionFactory的建立SqlSession的方法傳遞ExecutorType型別引數。

12. Mybatis對映檔案中,如果A標籤通過include引用了B標籤的內容,請問,B標籤能否定義在A標籤的後面,還是說必須定義在A標籤的前面?

雖然Mybatis解析Xml對映檔案是按照順序解析的,但是,被引用的B標籤依然可以定義在任何地方,Mybatis都可以正確識別。

原理是,Mybatis解析A標籤,發現A標籤引用了B標籤,但是B標籤尚未解析到,尚不存在,此時,Mybatis會將A標籤標記為未解析狀態,然後繼續解析餘下的標籤,包含B標籤,待所有標籤解析完畢,Mybatis會重新解析那些被標記為未解析的標籤,此時再解析A標籤時,B標籤已經存在,A標籤也就可以正常解析完成了。

13. 簡述Mybatis的Xml對映檔案和Mybatis內部資料結構之間的對映關係?

Mybatis將所有Xml配置資訊都封裝到All-In-One重量級物件Configuration內部。在Xml對映檔案中,<parameterMap>標籤會被解析為ParameterMap物件,其每個子元素會被解析為ParameterMapping物件。<resultMap>標籤會被解析為ResultMap物件,其每個子元素會被解析為ResultMapping物件。每一個<select>、<insert>、<update>、<delete>標籤均會被解析為MappedStatement物件,標籤內的sql會被解析為BoundSql物件。Object Relational Mapping物件關係對映

14為什麼說Mybatis是半自動ORM對映工具?它與全自動的區別在哪裡?

Hibernate屬於全自動ORM對映工具,使用Hibernate查詢關聯物件或者關聯集合物件時,可以根據物件關係模型直接獲取,所以它是全自動的。而Mybatis在查詢關聯物件或關聯集合物件時,需要手動編寫sql來完成,所以,稱之為半自動ORM對映工具。

15介面繫結有幾種實現方式,分別是怎麼實現的?

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

16什麼情況下用註解繫結,什麼情況下用xml繫結

當Sql語句比較簡單時候,用註解繫結,

當SQL語句比較複雜時候,用xml繫結,一般用xml繫結的比較多

17 like的使用

1.  CONCAT('%',#{userName},'%')

2.  '%${userName}%'

3.  '%'||#{userName}||'%'

18 mybatis快取

Mybatis的一級快取是指SqlSession。一級快取的作用域是一個SqlSession。Mybatis預設開啟一級快取。

在同一個SqlSession中,執行相同的查詢SQL,第一次會去查詢資料庫,並寫到快取中;第二次直接從快取中取。當執行SQL時兩次查詢中間發生了增刪改操作,則SqlSession的快取清空。

Mybatis的二級快取是指mapper對映檔案。二級快取的作用域是同一個namespace下的mapper對映檔案內容,多個SqlSession共享。

在同一個namespace下的mapper檔案中,執行相同的查詢SQL,第一次會去查詢資料庫,並寫到快取中;第二次直接從快取中取。當執行SQL時兩次查詢中間發生了增刪改操作,則二級快取清空。

如何開啟二級快取:在配置檔案中新增<settings name=”cacheEnabled” value=”true”>預設為true。在對映檔案中新增<cache></cache>

19 MyBatis的好處是什麼

mybatis把sql語句從Java源程式中獨立出來,

放在單獨的XML檔案中編寫,給程式的維護帶來了很大便利。

mybatis封裝了底層JDBC API的呼叫細節,並能自動將結果集轉換成JavaBean物件,大大簡化了Java資料庫程式設計的重複工作。

因為mybatis需要程式設計師自己去編寫sql語句,

程式設計師可以結合資料庫自身的特點靈活控制sql語句,

因此能夠實現比hibernate等全自動orm框架更高的查詢效率,能夠完成複雜查詢。

20. hibernate與mybatis的區別

                                     hibernate

                                      mybatis

全自動框架

半自動,需要手寫sql語句

sql優化修改較複雜

sql優化簡單,修改簡單

多表關聯操作比較繁瑣

多表操作簡單

對第三方框架支援較好

對第三方框架支援弱

需求不怎麼變化的企業級專案erpcrmoa

需求經常變化的網際網路專案

不支援動態sql

支援動態sql

sql層次較混亂

集中管理sql語句

21. MyBatis 配置 mappers 

第一種:使用相對路徑進行配置。

  1. <mappers>
  2.     <mapper resource="org/mybatis/mappers/UserMapper.xml"/>
  3.     <mapper resource="org/mybatis/mappers/ProductMapper.xml"/>
  4.     <mapper resource="org/mybatis/mappers/ManagerMapper.xml"/>
  5. </mappers>

第二種:使用絕對路徑進行配置。示例程式碼如下:

  1. <mappers>
  2.     <mapper url="file:///var/mappers/UserMapper.xml"/>
  3.     <mapper url="file:///var/mappers/ProductMapper.xml"/>
  4.     <mapper url="file:///var/mappers/ManagerMapper.xml"/>
  5. </mappers>

第三種:使用介面資訊進行配置。示例程式碼如下:

  1. <mappers>
  2.     <mapper class="org.mybatis.mappers.UserMapper"/>
  3.     <mapper class="org.mybatis.mappers.ProductMapper"/>
  4.     <mapper class="org.mybatis.mappers.ManagerMapper"/>
  5. </mappers>

第四種:使用介面所在包進行配置。示例如下:

  1. <mappers>
  2.     <package name="org.mybatis.mappers"/>
  3. </mappers>