二级缓存:
1、 需要在SqlMapper.xml里配置二级缓存总开关
"lazyLoadingEnabled" value="true"
/>
"aggressiveLazyLoading" value="false"
/>
"cacheEnabled" value="true"/>
2、在UserMapper.xml里配置
"120000">
3、 在结果映射的pojo中还包括了pojo,都要实现java.io.serializable接口
是mapper级别的(mapper同一个命名空间),mapper以命名空间为单位创建缓存数据结构,结构是map
每次查询先看是否开启二级缓存,如果开启从二级缓存的数据结构中取缓存数据:
List list = (List) tcm.getObject(cache,key);
如果从二级缓存没有取到,再从二级缓存中找,如果一级缓存也没有,从数据库查询。
Mybatis二级缓存需要将查询结果映射的pojo实现java.io.serializable接口,如果不实现则抛出异常:
org.apache.ibatis.cache.CacheException: Error serializing
object. Cause: java.io.NotSerializableException:
cn.itcast.mybatis.po.User
二级缓存可以将内存的数据写到磁盘,存在对象的序列化和反序列化问题,所以要实现java.io.serializable接口。
如果结果映射的pojo中还包括了pojo,都要实现java.io.serializable接口。
测试代码:
//二级缓存的测试
@Test
public void testCache2() throws Exception {
SqlSession sqlSession1 =
sqlSessionFactory.openSession();
SqlSession sqlSession2 =
sqlSessionFactory.openSession();
UserMapper userMapper1 =
sqlSession1.getMapper(UserMapper.class);
UserMapper userMapper2 =
sqlSession2.getMapper(UserMapper.class);
//第一次查询用户id为1的用户
User user =
userMapper1.findUserById(1);
System.out.println(user);
sqlSession1.close();
//第二次查询用户id为1的用户
User user2 =
userMapper2.findUserById(1);
System.out.println(user2);
sqlSession2.close();
}
测试日志:
DEBUG [main] - Checking to see if class
cn.itcast.mybatis.mapper.CacheTest matches criteria [is assignable
to Object]
DEBUG [main] - Checking to see if class
cn.itcast.mybatis.mapper.OrdersMapperCustom matches criteria [is
assignable to Object]
DEBUG [main] - Checking to see if class
cn.itcast.mybatis.mapper.OrdersMapperCustomTest matches criteria
[is assignable to Object]
DEBUG [main] - Checking to see if class
cn.itcast.mybatis.mapper.UserMapper matches criteria [is assignable
to Object]
DEBUG [main] - Checking to see if class
cn.itcast.mybatis.mapper.UserMapperTest matches criteria [is
assignable to Object]
DEBUG [main] - Cache Hit Ratio
[cn.itcast.mybatis.mapper.UserMapper]:
0.0
//表示二级缓存中没有需要查寻数据库
DEBUG [main] - Opening JDBC Connection
DEBUG [main] - Created connection 6961504.
DEBUG [main] - Setting autocommit to false on JDBC Connection
[com.mysql.jdbc.JDBC4Connection@6a3960]
DEBUG [main] - ==> Preparing: SELECT * FROM
USER WHERE id= ?
DEBUG [main] - ==> Parameters: 1(Integer)
DEBUG [main] -
<== Total: 1
User [id=1, username=测试用户1, birthday=Fri Feb 03 00:00:00 CST 2017,
sex=2, address=中国.北京, detail=null, score=null]
DEBUG [main] - Resetting autocommit to true on JDBC Connection
[com.mysql.jdbc.JDBC4Connection@6a3960]
DEBUG [main] - Closing JDBC Connection
[com.mysql.jdbc.JDBC4Connection@6a3960]
DEBUG [main] - Returned connection 6961504 to pool.
此时报了一个错:
org.apache.ibatis.cache.CacheException: Error
serializing object. Cause:
java.io.NotSerializableException:
cn.itcast.mybatis.po.User
at
org.apache.ibatis.cache.decorators.SerializedCache.serialize(SerializedCache.
at
org.apache.ibatis.cache.decorators.SerializedCache.putObject(SerializedCache.
at
org.apache.ibatis.cache.decorators.LoggingCache.putObject(LoggingCache.
at
org.apache.ibatis.cache.decorators.SynchronizedCache.putObject(SynchronizedCache.
at
org.apache.ibatis.cache.decorators.TransactionalCache$AddEntry.commit(TransactionalCache.
这是因为:二级缓存可以将内存的数据写到磁盘,存在对象的序列化,所以要实现java.io.serializable接口。
如果结果映射的pojo中还包括了pojo,都要实现java.io.serializable接口。
所以要在pojo里都加上实现接口:public class Items implements
Serializable
pojo类实现java.io.serializable接口。
public class User implements Serializable...
public class Orders implements Serializable...
测试代码:
//二级缓存的测试:各个pojo类实现serializable接口后测
@Test
public void testCache2() throws Exception {
SqlSession sqlSession1 =
sqlSessionFactory.openSession();
SqlSession sqlSession2 =
sqlSessionFactory.openSession();
UserMapper userMapper1 =
sqlSession1.getMapper(UserMapper.class);
UserMapper userMapper2 =
sqlSession2.getMapper(UserMapper.class);
//第一次查询用户id为1的用户
User user =
userMapper1.findUserById(1);
System.out.println(user);
sqlSession1.close();
//第二次查询用户id为1的用户
User user2 =
userMapper2.findUserById(1);
System.out.println(user2);
sqlSession2.close();
}
测试日志:
DEBUG [main] - Checking to see if class
cn.itcast.mybatis.mapper.UserMapper matches criteria [is assignable
to Object]
DEBUG [main] - Checking to see if class
cn.itcast.mybatis.mapper.UserMapperTest matches criteria [is
assignable to Object]
DEBUG [main] - Opening JDBC Connection
DEBUG [main] - Created connection 17268681.
DEBUG [main] - Setting autocommit to
false on JDBC Connection
[com.mysql.jdbc.JDBC4Connection@1077fc9]
//没有刚才的错了:DEBUG
[main] - Cache Hit Ratio [cn.itcast.mybatis.mapper.UserMapper]:
0.0
DEBUG [main] - ==> Preparing: SELECT * FROM
USER WHERE id= ?
DEBUG [main] - ==> Parameters: 1(Integer)
DEBUG [main] -
<== Total: 1
User [id=1, username=测试用户1, birthday=Fri Feb 03 00:00:00 CST 2017,
sex=2, address=中国.北京, detail=null, score=null]
DEBUG [main] - Resetting autocommit to true on JDBC Connection
[com.mysql.jdbc.JDBC4Connection@1077fc9]
DEBUG [main] - Closing JDBC Connection
[com.mysql.jdbc.JDBC4Connection@1077fc9]
DEBUG [main] - Returned connection 17268681 to pool.
DEBUG [main] - Opening JDBC Connection
DEBUG [main] - Checked out connection 17268681 from pool.
DEBUG [main] - Setting autocommit to false on JDBC Connection
[com.mysql.jdbc.JDBC4Connection@1077fc9]
DEBUG [main] - ==> Preparing: SELECT * FROM
USER WHERE id= ?
DEBUG [main] - ==> Parameters: 1(Integer)
DEBUG [main] -
<== Total: 1
User [id=1, username=测试用户1, birthday=Fri Feb 03 00:00:00 CST 2017,
sex=2, address=中国.北京, detail=null, score=null]
DEBUG [main] - Resetting autocommit to true on JDBC Connection
[com.mysql.jdbc.JDBC4Connection@1077fc9]
DEBUG [main] - Closing JDBC Connection
[com.mysql.jdbc.JDBC4Connection@1077fc9]
DEBUG [main] - Returned connection 17268681 to pool.
禁用二级缓存:☆☆