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-----
[●●●●] 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.
b. 如果SqlSession调用了close()方法,会释放掉一级缓存PerpetualCache对象,一级缓存将不可用;
c. 如果SqlSession调用了clearCache(),会清空PerpetualCache对象中的数据,但是该对象仍可使用;
d.SqlSession中执行了任何一个update操作(update()、delete()、insert()) ,都会清空PerpetualCache对象的数据,但是该对象可以继续使用;
<settings>
<!-- 开启二级缓存 -->
<setting name="cacheEnabled" value="true"/>
</settings>
<?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>
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) | ==> 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----------