延遲載入、快取、spring與宣告式事務
阿新 • • 發佈:2018-11-03
什麼是延遲載入
- 延遲載入又稱(懶載入)
- resultMap中的 association 和 collection 標籤就具有延遲載入的功能(一對一,一對多的關係自帶延遲載入,在開發裡面最常用的)
- 作用是:什麼時候用什麼時候載入
設定延遲載入
<!--開啟延遲載入-->
<setting name="lazyLoadingEnabled" value="true"/>
<!--關閉積極載入-->
<setting name="aggressiveLazyLoading" value="false" />
<setting name="lazyLoadTriggerMethods" value=""/>(呼叫toString無效時載入)
- 查詢主表的資訊(根據id來進行查詢,子查詢在resultMap(select="")如果是另一個包引入進來要加上完整的包名和類名,關聯的欄位)
呼叫其方法時,會走子查詢;
沒有載入延遲的時候控制檯顯示
- 會輸出兩句 查詢
載入延遲的時候控制檯顯示
- 獲取誰,就輸出誰的查詢
快取
- 好處:提高載入的速度,同樣的資料,不用一直查詢資料庫
- 缺點;可能查詢出髒資料;
一級快取:(一級快取的作用域是針對於我們的sqlsession(出了sqlsession 就沒有一級快取);預設一級快取自動開啟;
- 如果是要關閉一級快取,需要呼叫其commit()方法;
public class Test {
public static void main(String[] args) {
String path = "mybatis-config.xml";
try {
InputStream is = Resources.getResourceAsStream(path);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
//得到sqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
RoleMapper roleMapper = sqlSession.getMapper(RoleMapper.class);
Role role = roleMapper.selectByIdRole(2);
System.out.println(role.getRoleName());
//sqlSession.commit(); 未呼叫commit()
System.out.println("-------分割線--------");
RoleMapper roleMapper1= sqlSession.getMapper(RoleMapper.class);
Role role1= roleMapper1.selectByIdRole(2);
System.out.println(role1.getRoleName());
未呼叫 commit()釋出方法程式碼顯示
第二個經理就是在快取中獲取
呼叫 commit()釋出方法程式碼顯示
二級快取:(是針對於整個mapper(namespace=“com.offcn.dao.UserMapper”))只要在同一個mapper中,快取都有效果;
- 配置二級快取要注意(settings 裡面配置兩句話(開啟快取配置的按鈕,第二個是要把你的物件序列化,
- 第三個就是要把你的namespace 配置
標籤,這樣就配置了二級快取(用二級快取的時候,一定要sqlsession.commit()(關閉一級快取,載入二級快取)), - 步驟:在nameSpace 加上 cache;重新整理二級快取的方法:sqlSession.clearCache();禁用:
需要新增 cache
<mapper namespace="com.offcn.dao.RoleMapper">
<cache />
<select id="selectByIdRole" parameterType="int" resultType="Role">
select * from smbms_role where id=#{id}
</select>
</mapper>
自定義快取
- 第一步 匯入jar包
- 匯入一個mybatis-spring-1.2.0.jar
- 第二步 所有的都是由spring來進行管理 ,寫spring 的核心配置檔案
- applicationContext.xml(第一個bean 獲取連線資料來源,
- 第二個bean 獲取獲取sqlSessionFactroy(引入資料庫資源(dataSource) 第二個引入myBatis 核心配置檔案)
- 第三個bean (配置dao層 第一個是通過這個物件.MapperFactoryBean(引入你的介面的類,第二個是你的sqlSessionFactroy)"(第二種方式是MapperScannerConfigurer )))
spring 與 宣告式事務()
- 第一步: 引入資料庫的配置資訊(dataSource)
- 第二步 :配置dao 層 配置服務層
- 第三步: 配置事物管理器DataSourceTransactionManager (引入資料來源資源,也就是dataSource)
- 第四步 :定義事務通知(一種不用註解)(用註解)
- ( 代表對應的方法名 第二個代表是事物的傳播行為,事物失效的時間,事物的隔離級別–> <!– 指定異常進行回滾 這個代表引數的意思 )
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<!-- <property name="url">
<value><![CDATA[jdbc:mysql://127.0.0.1:3306/smbms?
useUnicode=true&characterEncoding=utf-8]]></value>
</property> -->
<property name="url" value="jdbc:mysql://127.0.0.1:3306/smbms?
useUnicode=true&characterEncoding=utf-8" />
<property name="username" value="root" />
<property name="password" value="root" />
</bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!--引入資料庫資源-->
<property name="dataSource" ref="dataSource"></property>
<!--載入mybatis核心配置檔案-->
<property name="configLocation" value="classpath:mybatis-config.xml"></property>
</bean>
<!--配置userDao-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.offcn.mapper"></property>
</bean>
<!--定義一個事物管理器-->
<bean id="transactionManger" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!--引入資料來源-->
<property name="dataSource" ref="dataSource"></property>
</bean>
<!--定義事物通知-->
<tx:advice id="txAdvice" transaction-manager="transactionManger">
<tx:attributes>
<!--name代表對應的方法名 第二個代表是事物的傳播行為,事物失效的時間,事物的隔離級別--> <!--指定異常進行回滾-->
<tx:method name="find" propagation="SUPPORTS" timeout="-1" isolation="DEFAULT" />
<tx:method name="add" propagation="REQUIRED"></tx:method>
<tx:method name="*" propagation="REQUIRED"></tx:method>
</tx:attributes>
</tx:advice>
<!--定義切面-->
<aop:config>
<aop:pointcut id="serviceMethod" expression="execution(* com.offcn.service.UserService.*(..))"></aop:pointcut>
<aop:advisor advice-ref="txAdvice" pointcut-ref="serviceMethod"></aop:advisor>
</aop:config>
public class UserServiceImpl implements UserService {
private UserMapper userMapper;
public void setUserMapper(UserMapper userMapper) {
this.userMapper = userMapper;
}
@Override
public void addUser(List<User> userList) {
for (User user: userList) {
userMapper.addUser(user);
}
}
}
第二種方式用的關鍵的註解 ()
<!--自動掃描包-->
<context:component-scan base-package="com.offcn.service"/>
<!--開啟註解驅動-->
<tx:annotation-driven/>
- 在 類前面 也就是你的service 的類上 @Transactional
- 再到你的方法上配置具體的 @Transactional(propagation = Propagation.REQUIRED) 等同於 <tx:method name="*" propagation=“REQUIRED” />
- 前面學過的註解 dao層的註解 @Repository service 層的@service @Autowired 按照型別
@Service("userSerbice")
/*事務的註解*/
@Transactional
public class UserServiceImpl implements UserService {
@Resource
private UserMapper userMapper;
public void setUserMapper(UserMapper userMapper) {
this.userMapper = userMapper;
}
@Override
@Transactional(propagation = Propagation.REQUIRED)
/*REQUIRED預設的,除了查詢都用這個*/
public void addUser(List<User> userList) {
for (User user: userList) {
userMapper.addUser(user);
}
}
}