Mybatis常見面試題 一

一、#{}和${}的區別是什麼?

注:這道題是面試官面試我同事的。java

答:${}是Properties文件中的變量佔位符,它能夠用於標籤屬性值和sql內部,屬於靜態文本替換,好比${driver}會被靜態替換爲com.mysql.jdbc.Driver。#{}是sql的參數佔位符,Mybatis會將sql中的#{}替換爲?號,在sql執行前會使用PreparedStatement的參數設置方法,按序給sql的?號佔位符設置參數值,好比ps.setInt(0, parameterValue),#{item.name}的取值方式爲使用反射從參數對象中獲取item對象的name屬性值,至關於param.getItem().getName()。mysql

二、Xml映射文件中,除了常見的select|insert|updae|delete標籤以外,還有哪些標籤?

注:這道題是京東面試官面試我時問的。面試

答:還有不少其餘的標籤,<resultMap>、<parameterMap>、<sql>、<include>、<selectKey>,加上動態sql的9個標籤,trim|where|set|foreach|if|choose|when|otherwise|bind等,其中<sql>爲sql片斷標籤,經過<include>標籤引入sql片斷,<selectKey>爲不支持自增的主鍵生成策略標籤。sql

三、最佳實踐中,一般一個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中,每個<select>、<insert>、<update>、<delete>標籤,都會被解析爲一個MappedStatement對象。緩存

Dao接口裏的方法,是不能重載的,由於是全限名+方法名的保存和尋找策略。數據結構

Dao接口的工做原理是JDK動態代理,Mybatis運行時會使用JDK動態代理爲Dao接口生成代理proxy對象,代理對象proxy會攔截接口方法,轉而執行MappedStatement所表明的sql,而後將sql執行結果返回。mybatis

四、Mybatis是如何進行分頁的?分頁插件的原理是什麼?

注:我出的。app

答:Mybatis使用RowBounds對象進行分頁,它是針對ResultSet結果集執行的內存分頁,而非物理分頁,能夠在sql內直接書寫帶有物理分頁的參數來完成物理分頁功能,也可使用分頁插件來完成物理分頁。工具

分頁插件的基本原理是使用Mybatis提供的插件接口,實現自定義插件,在插件的攔截方法內攔截待執行的sql,而後重寫sql,根據dialect方言,添加對應的物理分頁語句和物理分頁參數。

舉例:select * from student,攔截sql後重寫爲:select t.* from (select * from student)t limit 0,10

五、簡述Mybatis的插件運行原理,以及如何編寫一個插件。

注:我出的。

答:Mybatis僅能夠編寫針對ParameterHandler、ResultSetHandler、StatementHandler、Executor這4種接口的插件,Mybatis使用JDK的動態代理,爲須要攔截的接口生成代理對象以實現接口方法攔截功能,每當執行這4種接口對象的方法時,就會進入攔截方法,具體就是InvocationHandler的invoke()方法,固然,只會攔截那些你指定須要攔截的方法。

實現Mybatis的Interceptor接口並複寫intercept()方法,而後在給插件編寫註解,指定要攔截哪個接口的哪些方法便可,記住,別忘了在配置文件中配置你編寫的插件。

六、Mybatis執行批量插入,能返回數據庫主鍵列表嗎?

注:我出的。

答:能,JDBC都能,Mybatis固然也能。

七、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的功能。

八、Mybatis是如何將sql執行結果封裝爲目標對象並返回的?都有哪些映射形式?

注:我出的。

答:第一種是使用<resultMap>標籤,逐必定義列名和對象屬性名之間的映射關係。第二種是使用sql列的別名功能,將列別名書寫爲對象屬性名,好比T_NAME AS NAME,對象屬性名通常是name,小寫,可是列名不區分大小寫,Mybatis會忽略列名大小寫,智能找到與之對應對象屬性名,你甚至能夠寫成T_NAME AS NaMe,Mybatis同樣能夠正常工做。

有了列名與屬性名的映射關係後,Mybatis經過反射建立對象,同時使用反射給對象的屬性逐一賦值並返回,那些找不到映射關係的屬性,是沒法完成賦值的。

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

注:我出的。

答:能,Mybatis不只能夠執行一對1、一對多的關聯查詢,還能夠執行多對一,多對多的關聯查詢,多對一查詢,其實就是一對一查詢,只須要把selectOne()修改成selectList()便可;多對多查詢,其實就是一對多查詢,只須要把selectOne()修改成selectList()便可。

關聯對象查詢,有兩種實現方式,一種是單獨發送一個sql去查詢關聯對象,賦給主對象,而後返回主對象。另外一種是使用嵌套查詢,嵌套查詢的含義爲使用join查詢,一部分列是A對象的屬性值,另一部分列是關聯對象B的屬性值,好處是隻發一個sql查詢,就能夠把主對象和其關聯對象查出來。

那麼問題來了,join查詢出來100條記錄,如何肯定主對象是5個,而不是100個?其去重複的原理是<resultMap>標籤內的<id>子標籤,指定了惟一肯定一條記錄的id列,Mybatis根據<id>列值來完成100條記錄的去重複功能,<id>能夠有多個,表明了聯合主鍵的語意。

一樣主對象的關聯對象,也是根據這個原理去重複的,儘管通常狀況下,只有主對象會有重複記錄,關聯對象通常不會重複。

舉例:下面join查詢出來6條記錄,1、二列是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 |

十、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()方法的調用。這就是延遲加載的基本原理。

固然了,不光是Mybatis,幾乎全部的包括Hibernate,支持延遲加載的原理都是同樣的。

十一、Mybatis的Xml映射文件中,不一樣的Xml映射文件,id是否能夠重複?

注:我出的。

答:不一樣的Xml映射文件,若是配置了namespace,那麼id能夠重複;若是沒有配置namespace,那麼id不能重複;畢竟namespace不是必須的,只是最佳實踐而已。

緣由就是namespace+id是做爲Map<String, MappedStatement>的key使用的,若是沒有namespace,就剩下id,那麼,id重複會致使數據互相覆蓋。有了namespace,天然id就能夠重複,namespace不一樣,namespace+id天然也就不一樣。

十二、Mybatis中如何執行批處理?

注:我出的。

答:使用BatchExecutor完成批處理。

1三、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生命週期範圍內。

1四、Mybatis中如何指定使用哪種Executor執行器?

注:我出的

答:在Mybatis配置文件中,能夠指定默認的ExecutorType執行器類型,也能夠手動給DefaultSqlSessionFactory的建立SqlSession的方法傳遞ExecutorType類型參數。

1五、Mybatis是否能夠映射Enum枚舉類?

注:我出的

答:Mybatis能夠映射枚舉類,不單能夠映射枚舉類,Mybatis能夠映射任何對象到表的一列上。映射方式爲自定義一個TypeHandler,實現TypeHandler的setParameter()和getResult()接口方法。TypeHandler有兩個做用,一是完成從javaType至jdbcType的轉換,二是完成jdbcType至javaType的轉換,體現爲setParameter()和getResult()兩個方法,分別表明設置sql問號佔位符參數和獲取列查詢結果。

1六、Mybatis映射文件中,若是A標籤經過include引用了B標籤的內容,請問,B標籤可否定義在A標籤的後面,仍是說必須定義在A標籤的前面?

注:我出的

答:雖然Mybatis解析Xml映射文件是按照順序解析的,可是,被引用的B標籤依然能夠定義在任何地方,Mybatis均可以正確識別。

原理是,Mybatis解析A標籤,發現A標籤引用了B標籤,可是B標籤還沒有解析到,尚不存在,此時,Mybatis會將A標籤標記爲未解析狀態,而後繼續解析餘下的標籤,包含B標籤,待全部標籤解析完畢,Mybatis會從新解析那些被標記爲未解析的標籤,此時再解析A標籤時,B標籤已經存在,A標籤也就能夠正常解析完成了。

1七、簡述Mybatis的Xml映射文件和Mybatis內部數據結構之間的映射關係?

注:我出的

答:Mybatis將全部Xml配置信息都封裝到All-In-One重量級對象Configuration內部。在Xml映射文件中,<parameterMap>標籤會被解析爲ParameterMap對象,其每一個子元素會被解析爲ParameterMapping對象。<resultMap>標籤會被解析爲ResultMap對象,其每一個子元素會被解析爲ResultMapping對象。每個<select>、<insert>、<update>、<delete>標籤均會被解析爲MappedStatement對象,標籤內的sql會被解析爲BoundSql對象。

1八、爲何說Mybatis是半自動ORM映射工具?它與全自動的區別在哪裏?

注:我出的

答:Hibernate屬於全自動ORM映射工具,使用Hibernate查詢關聯對象或者關聯集合對象時,能夠根據對象關係模型直接獲取,因此它是全自動的。而Mybatis在查詢關聯對象或關聯集合對象時,須要手動編寫sql來完成,因此,稱之爲半自動ORM映射工具。

面試題看似都很簡單,可是想要能正確回答上來,一定是研究過源碼且深刻的人,而不是僅會使用的人或者用的很熟的人,以上全部面試題及其答案所涉及的內容,在個人Mybatis系列博客中都有詳細講解和原理分析。

相關文章
相關標籤/搜索