天天看點

MyBatis基礎面試題及答案(2)

16、Mybatis 能執行一對一、一對多的關聯查詢嗎?都有哪些實作方式,以及它們之間的差別?

答:能,Mybatis 不僅可以執行一對一、一對多的關聯查詢,還可以執行多對一,多對多的關聯查詢,多對一查詢,其實就是一對一查詢,隻需要把selectOne()修改為 selectList()即可;多對多查詢,其實就是一對多查詢,隻需要把 selectOne()修改為 selectList()即可。關聯對象查詢,有兩種實作方式,一種是單獨發送一個sql去查詢關聯對象,賦給主對象,然後傳回主對象。另一種是使用嵌套查詢,嵌套查詢的含義為使用 join 查詢,一部分列是 A 對象的屬性值,另外一部分列是關聯對象 B 的屬性值,好處是隻發一個 sql 查詢,就可以把主對象和其關聯對象查出來。

17、MyBatis 裡面的動态 Sql 是怎麼設定的?用什麼文法?

答:MyBatis 裡面的動态 Sql 一般是通過 if 節點來實作,通過 OGNL 文法來實作,但是如果要寫的完整,必須配合where,trim 節點,where 節點是判斷包含節點有内容就插入 where,否則不 插入,trim 節點是用來判斷如果動态語句是以and 或 or 開始,那麼會自動把這個 and 或者 or取掉。

18、Mybatis 是如何将 sql 執行結果封裝為目标對象并傳回的?都有哪些映射形式?

答:

第一種是使用标簽,逐一定義列名和對象屬性名之間的映射關系。

第二種是使用 sql列的别名功能,将列别名書寫為對象屬性名,比如 T_NAME AS NAME,對象屬性名一般是name,小寫,但是列名不區分大小寫,Mybatis 會忽略列名大小寫,智能找到與之對應對象屬性名,你甚至可以寫成 T_NAME AS NaMe,Mybatis 一樣可以正常工作。 有了列名與屬性名的映射關系後,Mybatis通過反射建立對象,同時使用反射給對象的屬性逐一指派并傳回,那些找不到映射關系的屬性,是無法完成指派的。

19、Xml 映射檔案中,除了常見的 select|insert|updae|delete 标簽之外,還有哪些标簽?

還有很多其他的标簽,

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

加上動态 sql 的 9 個标簽, trim|where|set|foreach|if|choose|when|otherwise|bind

等,其中為 sql 片段标簽,通過标簽引入 sql 片段,為不支援自增的主鍵生成政策标簽。

20、當實體類中的屬性名和表中的字段名不一樣,如果将查詢的結果封裝到指定 pojo?

1)通過在查詢的 sql 語句中定義字段名的别名。

2)通過<resultMap>來映射字段名和實體類屬性名的一一對應的關系。

21、模糊查詢 like 語句該怎麼寫

1)在 java 中拼接通配符,通過#{}指派

2)在 Sql 語句中拼接通配符 (不安全,會引起 Sql 注入)

22、通常一個 Xml 映射檔案,都會寫一個 Dao 接口與之對應, Dao 的工作原理,是否可以重載?

不能重載,因為通過 Dao 尋找 Xml 對應的 sql 的時候全限名+方法名的儲存和尋找政策。接口工作原理為 jdk動态代理原理,運作時會為 dao 生成 proxy,代理對象會攔截接口方法,去執行對應的 sql 傳回資料。

23、Mybatis 映射檔案中,如果 A 标簽通過 include 引用了 B 标簽的内容,請問,B 标簽能否定義在 A 标簽的後面,還是說必須定義在 A 标簽的前面?

雖然 Mybatis 解析 Xml 映射檔案是按照順序解析的,但是,被引用的 B 标簽依然可以定義在任何地方,Mybatis都可以正确識别。原理是,Mybatis 解析 A 标簽,發現 A 标簽引用了 B 标簽,但是 B标簽尚未解析到,尚不存在,此時,Mybatis 會将 A 标簽标記為未解析狀态,然後繼續解析餘下的标簽,包含 B标簽,待所有标簽解析完畢,Mybatis 會重新解析那些被标記為未解析的标簽,此時再解析 A 标簽時,B 标簽已經存在,A标簽也就可以正常解析完成了。

24、Mybatis 的 Xml 映射檔案中,不同的 Xml 映射檔案,id 是否可以重複?

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

25、Mybatis 中如何執行批處理?

使用 BatchExecutor 完成批處理。

26、Mybatis 都有哪些 Executor 執行器?它們之間的差別是什麼?

Mybatis 有三種基本的 Executor 執行器,

SimpleExecutor、ReuseExecutor、BatchExecutor。

1)SimpleExecutor:每執行一次 update 或 select,就開啟一個 Statement 對象,用完立刻關閉

Statement 對象。 2)ReuseExecutor:執行 update 或 select,以 sql 作為key 查找

Statement 對象,存在就使用,不存在就建立,用完後,不關閉 Statement 對象,而是放置于 Map

3)BatchExecutor:完成批處理。

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

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

28、Mybatis 執行批量插入,能傳回資料庫主鍵清單嗎?

能,JDBC 都能,Mybatis 當然也能。

29、Mybatis 是否可以映射 Enum 枚舉類?

Mybatis 可以映射枚舉類,不單可以映射枚舉類,Mybatis 可以映射任何對象到表的一列上。映射方式為自定義一個TypeHandler,實作 TypeHandler 的 setParameter()和getResult()接口方法。TypeHandler 有兩個作用,一是完成從 javaType 至 jdbcType 的轉換, 二是完成jdbcType 至 javaType 的轉換,展現為 setParameter()和 getResult()兩個方法,分别 代表設定sql 問号占位符參數和擷取列查詢結果。

30、如何擷取自動生成的(主)鍵值?

配置檔案設定 usegeneratedkeys 為 true

31、在 mapper 中如何傳遞多個參數?

1)直接在方法中傳遞參數,xml 檔案用#{0} #{1}來擷取

2)使用 @param 注解:這樣可以直接在 xml檔案中通過#{name}來擷取

32、resultType resultMap 的差別?

1)類的名字和資料庫相同時,可以直接設定 resultType 參數為 Pojo 類

2)若不同,需要設定 resultMap将結果名字和 Pojo 名字進行轉換

33、使用 MyBatis 的 mapper 接口調用時有哪些要求?

1)Mapper 接口方法名和 mapper.xml 中定義的每個 sql 的 id 相同 > 2)Mapper 接口方法的輸入參數類型和mapper.xml 中定義的每個 sql 的 parameterType 的 類型相同

3)Mapper 接口方法的輸出參數類型和mapper.xml 中定義的每個 sql 的 resultType 的類型 相同

4)Mapper.xml 檔案中的 namespace即是 mapper 接口的類路徑。

34、Mybatis 比 IBatis 比較大的幾個改進是什麼?

1)有接口綁定,包括注解綁定 sql 和 xml 綁定 Sql

2)動态 sql 由原來的節點配置變成 OGNL 表達式

3)在一對一,一對多的時候引進了association,在一對多的時候引入了 collection 節點,不過都是在 resultMap裡面配置

35、IBatis 和 MyBatis 在核心處理類分别叫什麼?

IBatis 裡面的核心處理類交 SqlMapClient,MyBatis 裡面的核心處理類叫做 SqlSession。

36、IBatis 和 MyBatis 在細節上的不同有哪些?

1)在 sql 裡面變量命名有原來的#變量# 變成了#{變量}

2)原來的$變量$變成了${變量}

3)原來在 sql 節點裡面的class 都換名字交 type

4)原來的 queryForObject queryForList 變成了 selectOne

selectList

5)原來的别名設定在映射檔案裡面放在了核心配置檔案裡