1、mybatis的延遲加載
需要時才加載關聯對象,而不是查詢主對象時,立刻加載所有關聯對象,這樣可以提高查詢性能并減少不必要的數據庫訪問,例如:一個訂單表包含著商品列表(一對多),當查詢訂單對象時,不會立刻從數據庫加載商品列表,而是等到第一次真正使用到商品時采取查詢數據庫
一般一對多,多對多的場景適用延遲加載,如何開啟?
(1)局部開啟:在<collection ... fetchType="lazy">
??(2)全局開啟:
mybatis.configuration.lazy-loading-enable=true? #開啟全局懶加載
mybatis.configuration.aggressiv-lazy-loading=false #關閉立即加載
注意:mybatis的核心在于使用動態代理技術
1、在查詢主對象時,MyBatis 并不會直接創建關聯對象或集合的實例。
2、而是會為這些關聯屬性或集合創建一個?代理對象,
3、當用戶代碼首次訪問這個代理對象的屬性或方法時,
4、代理對象會攔截這次調用,代理對象內部會檢查關聯數據是否已經被加載,
5、如果數據尚未加載,代理對象會根據 ResultMap 中 association 或 collection 標簽的 select 屬性指定的 Mapper 方法和 column 屬性提供的參數,發起一個新的數據庫查詢。
6、查詢結果(關聯數據)會被加載到代理對象中。
7、代理對象將加載的數據返回給用戶。后續對該代理對象的訪問將直接返回已加載的數據,不再觸發數據庫查詢(在同一個 SqlSession 生命周期內)
2、談談mybatis插件的原理
MyBatis 插件用于攔截 SQL 執行并增強其功能。插件基于 JDK 動態代理機制,在 MyBatis 初始化過程中為指定對象生成代理對象,當攔截對象執行某個方法時,代理會先執行插件中的邏輯,再執行原有邏輯.
? (1)插件類需要實現mybatis的interceptor接口,還需要通過注解標注該插件的攔截點
(2)攔截點就是指插件所能攔截的方法,mybtias允許攔截的方法如下:
【1】Executor:執行器的方法(有update(包含了update,insert,delete),query,commit,rollback,close等)
【2】statementHandler:查操作,增刪改操作,設置參數,sql的預編譯,批處理
【3】ParameterHandler: 獲取參數和設置參數
【4】ResultSetHandler:結果的組裝
3、如何獲取mybatis中自增的主鍵
在平時開發中,可能會遇到數據庫主鍵是自增的情況,這時我們保存數據時并不需要指定主鍵,可是很多時候都需要獲取保存數據后生成的主鍵,怎么辦呢?
1、在mapper.xml中的insert標簽使用useGeneratedKeys="true" keyProPerty="id" keyColumn="id"
- useGeneratedKeys:是否自動生成主鍵,默認false。
- keyColumn:數據庫中的自增主鍵的列名,默認是數據庫表的第一列,當主鍵列不是表中的第一列的時候需要設置。
- keyProperty:返回的主鍵值賦給實體類中哪個屬性。
2、在insert中嵌套使用selectKey標簽
<insert id="insertBook" parameterType="com.learn.entity.Book"><selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">SELECT LAST_INSERT_ID()</selectKey>INSERT INTO BOOK(NAME) VALUES(#{name})</insert>
4、不同的Mapper中的id是否可以相同
可以相同,每一個映射文件的namespace都會設置對應的mapper接口的全類路徑名稱,也就是保證了每個一個mapper文件的namespace都是唯一的,只需要滿足同一個映射文件的id是不同即可
5、myabtis中屬性名和字段名不一致怎么辦?
(1)在sql語句中通過別名來映射到java的屬性
(2)通過resultMap配置映射關系
(3)如果是因為下劃線轉換為駝峰命名造成的不一致:mapUnderscoreToCamelCase
6、談談你對mybatis中的Executor理解
在MyBatis中,執行器(Executor)是核心組件之一,負責SQL語句的生成和查詢緩存的維護。
Executor的類型有三個
- SIMPLE:? 默認 SimpleExecutor,每次操作都是一個新的Statement對象
- REUSE : ReuseExecutor,會根據SQL緩存Statement對象,實現Statement對象的復用,樣可以減少數據庫的準備和創建Statement的開銷
- BATCH: BatchExecutor 批處理,將所有的修改操作,直到調用flushStatements()方法時才一次性發送到數據庫執行。這種方式可以減少網絡往返次數,提高批量操作的效率。
7、如何設置mybatis中的Executor的類型
(1)可以通過SqlSessionFactory的openSession添加Executor參數
(2)配置文件mybatis.executor-type=batch
8、Mybatis中如何實現多個傳參
(1)使用@param? ??
public User selectUser(@Param("userName") String name, @Param("deptId") int deptId);<select id="selectUser" resultMap="UserResultMap">
select * from user
where user_name = #{userName} and dept_id = #{deptId}
</select>
(2)使用Map
public User selectUser(Map<String, Object> params);<select id="selectUser" parameterType="java.util.Map" resultMap="UserResultMap">
select * from user
where user_name = #{userName} and dept_id = #{deptId}
</select>
(3)使用java bean
public User selectUser(User user);<select id="selectUser" parameterType="com.test.User" resultMap="UserResultMap">
select * from user
where user_name = #{userName} and dept_id = #{deptId}
</select>
(4)基于參數順序傳參
public User selectUser(String name, int deptId);<select id="selectUser" resultMap="UserResultMap">
select * from user
where user_name = #{0} and dept_id = #{1}
</select>