記錄學習的點滴(MyBatis緩存機制學習)

1,一級緩存

UserDao.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"   
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">  
<mapper namespace="com.springmybatis.system.dao.UserDao">
<!-- 開啓二級緩存 -->
<cache />

<!-- 當爲select語句時: useCache默認爲true,表示會將本條語句的結果進行二級緩存。
flushCache默認爲false,表示任何時候語句被調用,都不會去清空本地緩存和二級緩存。
-->
<!--
當爲insert、update、delete語句時:useCache屬性在該情況下沒有。
flushCache默認爲true,表示任何時候語句被調用,都會導致本地緩存和二級緩存被清空。
-->
<select id="getUser" parameterType="com.springmybatis.system.model.User"
	resultType="java.util.Map" flushCache="false" useCache="false">
	SELECT * FROM IF_KIKAKU.USER_M WHERE user_name=#{userName}
	<if test="password != null ">AND entry_cd=#{password}</if>
</select>
</mapper>

實例

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations="classpath:applicationContext.xml")
public class MySqlSessionTest {
	@Autowired
	private SqlSessionFactory sqlSessionFactory;
	
	/**
	 * MyBatis一級緩存測試方法
	 */
	@Test
	public void mySqlSessionTest1() {
		SqlSession session = sqlSessionFactory.openSession();
		UserDao userDao = session.getMapper(UserDao.class);
		Map<String, Object> resMap1 = new HashMap<String, Object>();
		User userParam1 = new User();userParam1.setPassword("Test");
		userParam1.setUserName("TestTest");
		resMap1 = userDao.getUser(userParam1);
		System.out.println("----" + resMap1.get("USER_NAME") + "-----");
		//①
//		session.commit();
		//②
		// 清空緩存
//		session.close();
		Map<String, Object> resMap2 = new HashMap<String, Object>();
		User userParam2 = new User();userParam2.setPassword("Test");
		userParam2.setUserName("TestTest");
		resMap2 = userDao.getUser(userParam2);
		System.out.println("----" + resMap2.get("USER_NAME") + "-----");
	}
}

運行結果

[●●●●] DEBUG [main] getUser.debug(132) | ooo Using Connection [oracle.jdbc.driver.T4CConnection@39e3471d]
[●●●●] DEBUG [main] getUser.debug(132) | ==>  Preparing: SELECT * FROM IF_KIKAKU.USER_M WHERE user_name=? AND entry_cd=?
[●●●●] DEBUG [main] getUser.debug(132) | ==> Parameters: TestTest(String), Test(String)
[●●●●] DEBUG [main] getUser.debug(132) | <==      Total: 1
----TestTest-----
----TestTest-----

把①處註釋去掉,運行結果

[●●●●] DEBUG [main] getUser.debug(132) | ooo Using Connection [oracle.jdbc.driver.T4CConnection@7851de9b]
[●●●●] DEBUG [main] getUser.debug(132) | ==>  Preparing: SELECT * FROM IF_KIKAKU.USER_M WHERE user_name=? AND entry_cd=?
[●●●●] DEBUG [main] getUser.debug(132) | ==> Parameters: TestTest(String), Test(String)
[●●●●] DEBUG [main] getUser.debug(132) | <==      Total: 1
----TestTest-----
[●●●●] DEBUG [main] getUser.debug(132) | ooo Using Connection [oracle.jdbc.driver.T4CConnection@7851de9b]
[●●●●] DEBUG [main] getUser.debug(132) | ==>  Preparing: SELECT * FROM IF_KIKAKU.USER_M WHERE user_name=? AND entry_cd=?
[●●●●] DEBUG [main] getUser.debug(132) | ==> Parameters: TestTest(String), Test(String)
[●●●●] DEBUG [main] getUser.debug(132) | <==      Total: 1
----TestTest-----

把②處註釋去掉,運行結果裏面就會報錯。因爲第二次執行sql的時候,一級緩存已經被清除。
[●●●●] DEBUG [main] getUser.debug(132) | ooo Using Connection [oracle.jdbc.driver.T4CConnection@4ca41180]
[●●●●] DEBUG [main] getUser.debug(132) | ==>  Preparing: SELECT * FROM IF_KIKAKU.USER_M WHERE user_name=? AND entry_cd=?
[●●●●] DEBUG [main] getUser.debug(132) | ==> Parameters: TestTest(String), Test(String)
[●●●●] DEBUG [main] getUser.debug(132) | <==      Total: 1
----TestTest-----
[●●●●] DEBUG [main] DataSourceUtils.doReleaseConnection(327) | Returning JDBC Connection to DataSource
[●●●●] DEBUG [main] DirtiesContextTestExecutionListener.afterTestMethod(85) | After test method: context [DefaultTestContext@121157c9 testClass = MySqlSessionTest, testInstance =com.springmybatis.system.sqlsession.MySqlSessionTest@309a5663, testMethod = mySqlSessionTest1@MySqlSessionTest, testException = org.apache.ibatis.exceptions.PersistenceException:
### Error querying database.  Cause: org.apache.ibatis.executor.ExecutorException: Executor was closed.
一級緩存的週期
a. MyBatis在開啓一個數據庫會話時,會 創建一個新的SqlSession對象,SqlSession對象中會有一個新的Executor對象,Executor對象中持有一個新的PerpetualCache對象;當會話結束時,SqlSession對象及其內部的Executor對象還有PerpetualCache對象也一併釋放掉。
b. 如果SqlSession調用了close()方法,會釋放掉一級緩存PerpetualCache對象,一級緩存將不可用;
c. 如果SqlSession調用了clearCache(),會清空PerpetualCache對象中的數據,但是該對象仍可使用;
d.SqlSession中執行了任何一個update操作(update()、delete()、insert()) ,都會清空PerpetualCache對象的數據,但是該對象可以繼續使用;
開啓
mybatis-config.xml
    <settings>
        <!-- 開啓二級緩存 -->
        <setting name="cacheEnabled" value="true"/>
    </settings>
TestUserDao.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"   
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.springmybatis.system.dao.TestUserDao">
<!-- 開啓二級緩存 -->
<!-- eviction     :回收策略 -->
<!-- flushInterval:自動刷新時間 -->
<!-- size         :最多緩存對象數 -->
<!-- readOnly     :只讀 -->
<cache eviction="FIFO" flushInterval="60000" size="512" readOnly="true" />
	<select id="getUser" parameterType="com.springmybatis.system.model.TestUser" resultType="java.util.HashMap">
		select * from if_kikaku.test_user_m where user_id=#{userId}
	</select>
</mapper>
以上可知,開啓二級緩存的必備條件有三個
   1.  MyBatis支持二級緩存的總開關:全局配置變量參數   cacheEnabled=true
   2. 該select語句所在的Mapper,配置了<cache> 或<cached-ref>節點,並且有效
   3. 該select語句的參數 useCache=true(默認是true)
實例
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations="classpath:applicationContext.xml")
public class MySqlSessionTest {
	@Autowired
	private SqlSessionFactory sqlSessionFactory;

	/**
	 * MyBatis二級緩存測試方法
	 */
	@Test
	public void mySqlSessionTest2() {
        SqlSession session1 = sqlSessionFactory.openSession();
        TestUser userParam1 = new TestUser();userParam1.setUserId("1");
        Map<String, Object> resMap1 = new HashMap<String, Object>();
        resMap1 = session1.selectOne("com.springmybatis.system.dao.TestUserDao.getUser", userParam1);
        System.out.println("----------"+resMap1.get("PASSWORD")+"----------");
        session1.commit();
        
        SqlSession session2 = sqlSessionFactory.openSession();
        TestUser userParam2 = new TestUser();userParam2.setUserId("1");
        Map<String, Object> resMap2 = new HashMap<String, Object>();
        resMap2 = session2.selectOne("com.springmybatis.system.dao.TestUserDao.getUser", userParam2);
        System.out.println("----------"+resMap2.get("PASSWORD")+"----------");
        session2.commit();
	}
}
運行結果
[●●●●] DEBUG [main] getUser.debug(132) | ooo Using Connection [oracle.jdbc.driver.T4CConnection@61b51fe5]
[●●●●] DEBUG [main] getUser.debug(132) | ==>  Preparing: select * from if_kikaku.test_user_m where user_id=?
[●●●●] DEBUG [main] getUser.debug(132) | ==> Parameters: 1(String)
[●●●●] DEBUG [main] getUser.debug(132) | <==      Total: 1
----------PQER----------
[●●●●] DEBUG [main] LoggingCache.getObject(55) | Cache Hit Ratio [com.springmybatis.system.dao.TestUserDao]: 0.5
----------PQER----------








發佈了37 篇原創文章 · 獲贊 2 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章