文章目錄
- 數據庫事務管理
- 批處理
- 插件擴展
- 持久化和ORM
- 緩存機制
數據庫事務管理
通過注解方式: 在需要進行事務管理的方法上添加@Transactional注解,該注解可以用于類或方法上。在配置文件中開啟事務管理器,并指定事務管理器的類型和連接池等相關信息。
示例
java
@Transactional
public void updateUserInfo(UserInfo userInfo) {// 執行更新操作// ...
}
通過XML配置方式: 在Mapper XML文件中使用標簽來配置事務管理器,以及tx:advice標簽配置事務的傳播行為和異常處理策略。
xml
<transactions><transactionManager type="JDBC"><dataSource type="POOLED"><!-- 配置數據源 --></dataSource></transactionManager><tx:advice id="txAdvice" transaction-manager="transactionManager"><tx:attributes><tx:method name="update*" propagation="REQUIRED" rollback-for="Exception"/></tx:attributes></tx:advice>
</transactions>
在配置文件中,還需要配置事務管理器和數據源相關的信息。
xml
<environments default="development"><environment id="development"><transactionManager type="JDBC"><dataSource type="POOLED"><!-- 配置數據源 --></dataSource></transactionManager></environment>
</environments>
需要注意的是,事務管理器的類型和數據源的配置需根據具體的數據庫和連接池來進行配置。
另外,MyBatis還支持對事務的手動提交和回滾操作,可通過SqlSession實例的commit()和rollback()方法來手動控制事務的提交和回滾
java
SqlSession sqlSession = sqlSessionFactory.openSession();
try {// 執行數據庫操作sqlSession.commit();
} catch (Exception e) {sqlSession.rollback();
} finally {sqlSession.close();
}
以上方式配置和管理事務,可以保證MyBatis在執行數據庫操作時的數據一致性和事務的可靠性
批處理
批處理是指一次性執行多個數據庫操作語句的功能。這在某些場景下可以提高性能。
- 在MyBatis中,使用SqlSession的insert、update和delete方法來執行批處理。這些方法可以接受一個包含多個參數的集合,每個參數表示一次數據庫操作。例如:
java
List<User> userList = new ArrayList<>();
userList.add(new User("user1"));
userList.add(new User("user2"));SqlSession sqlSession = sqlSessionFactory.openSession();
try {sqlSession.insert("insertUser", userList);sqlSession.commit();
} finally {sqlSession.close();
}
-
在上面的示例中,insertUser是一個Mapper中的插入語句,userList是包含多個User對象的集合,表示多次插入操作。調用insert方法后,MyBatis會將每個User對象作為參數執行一次插入操作。
-
需要注意的是,為了提高批處理的性能,通常需要將SqlSession的autoCommit屬性設置為false,并在執行完批處理后手動調用commit方法提交事務。
- MyBatis還提供了一種更高效的方式來執行批處理,即使用批量插入/更新/刪除語句。這種方式可以通過在Mapper接口中定義一個返回類型為int的方法,并使用@InsertProvider、@UpdateProvider和@DeleteProvider注解來指定相應的動態SQL提供者。例如:
java
@Mapper
public interface UserMapper {@InsertProvider(type = BatchInsertProvider.class, method = "insert")int batchInsert(List<User> userList);
}public class BatchInsertProvider {public String insert(Map<String, Object> map) {List<User> userList = (List<User>) map.get("list");StringBuilder sb = new StringBuilder();sb.append("INSERT INTO user (username) VALUES ");for (User user : userList) {sb.append("(#{item.username}),");}sb.deleteCharAt(sb.length() - 1);return sb.toString();}
}List<User> userList = new ArrayList<>();
userList.add(new User("user1"));
userList.add(new User("user2"));int result = userMapper.batchInsert(userList);
- 上面的示例中,BatchInsertProvider是一個動態SQL提供者,根據傳入的參數動態生成批量插入語句。batchInsert方法接受一個包含多個User對象的集合,并返回插入成功的記錄數。
需要注意的是,使用批量插入/更新/刪除語句時,對應的Mapper方法的返回類型必須為int,表示插入/更新/刪除的記錄數。
插件擴展
插件是用于擴展和增強MyBatis框架功能的組件。它可以攔截MyBatis的執行過程,實現一些自定義的邏輯。
常用的MyBatis插件擴展
- 攔截器(Interceptor):Interceptor接口,可以在MyBatis執行的各個階段攔截方法調用,并加入自定義的邏輯。常見的用途包括日志記錄、權限控制、結果集處理等。
- 類型處理器(Type Handler):類型處理器用于將Java類型與數據庫中的數據類型進行轉換。可以通過實現TypeHandler接口,自定義類型轉換邏輯,以支持自定義的數據類型。
- 參數處理器(Parameter Handler):參數處理器用于將Java對象轉換為SQL語句的參數。通過實現TypeHandler接口,可以實現自定義的參數轉換邏輯。
- 數據源(DataSource):MyBatis默認使用的是JDBC連接池來管理數據庫連接。通過實現DataSource接口,可以自定義數據源,以實現對其他連接池的支持。
持久化和ORM
- 持久化就是程序的數據,在瞬時狀態(new)和持久狀態(數據庫等)之間轉化。通過數據庫操作進行轉化。
- 瞬態狀態指的是對象在沒有被持久化到數據庫之前的狀態。在瞬態狀態下,對象的屬性可能已經被賦值,但這些改變還沒有被保存到數據庫中。
- 持久狀態是指對象在數據庫中的持久化狀態,它提供了方便的數據庫訪問和操作方式,同時支持緩存以提高查詢效率。
- ORM.(O=javaBean)(R=關系型數據庫)(M=映射)
- JavaBean是指遵循特定命名約定和規范的Java類,用來封裝數據和提供訪問這些數據的方法。它是Java語言中一種編程規范。
- 關系型數據庫(Relational Database)是指采用了關系模型的數據庫管理系統。關系模型是由埃德加·科德提出的,它將數據組織為表格的形式,表格由行和列組成。關系型數據庫通過在不同表格之間建立關系(通過主鍵和外鍵),來表示實體之間的聯系。
- 映射是一個廣泛應用的概念,在不同的領域中有著不同的含義和作用,但核心的概念都是將一個對象或值關聯到另一個對象或值上的過程或規則。
- 注意:ORM這三方面要保持一致。任意部分的變動都要一起檢測。
緩存機制
- 一級緩存
- session級別的緩存。
- 默認都會有,不需要手動開啟。
- 線程不共享的。
- 當session關閉或者flush時。session清空。
- 二級緩存
- sessionFactroy級別的緩存。同一個namespace內的select會被緩存。
- 默認緩存不開啟。需要手動開啟。
- 線程共享。
- 當進行增刪改的時候,緩存將被清空。
- 二級緩存開啟的步驟
- 在mybatis的主配置文件中,開啟緩存
<configuration><settings><setting name="cacheEnable" value="true"/><setting name="lazyLoadingEnabled" value="false"/></settings>
</configuration>
- 在mapper中的設置緩存
<cacheeviction="FIFO" // 回收策略flushInterval="60000" // 緩存刷新的間隔時間size="512" // 緩存大小readOnly="true" /> // 默認時false,表示其他線程調用都是復制緩存對象。如果為true,線程使用的時原始的緩存對象