您的位置:首页 > 其它

记录学习的点滴(MyBatis缓存机制学习)

2016-09-26 17:37 495 查看
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对象的数据,但是该对象可以继续使用;
引用:http://blog.csdn.net/luanlouis/article/details/41280959

2,二级缓存
开启
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_kika
4000
ku.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----------






内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: