mysql mybatis 缓存_mybatis的二级缓存

本文详细介绍了MyBatis二级缓存的配置及使用,包括在SqlMapper.xml中开启缓存,设置缓存有效期,在UserMapper.xml中的配置。重点讨论了二级缓存如何基于命名空间创建数据结构,并解释了为何需要实现`java.io.Serializable`接口以解决对象序列化问题。通过测试代码展示了不实现接口时的异常以及实现接口后的正确运行情况。
摘要由CSDN通过智能技术生成

二级缓存:

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.

禁用二级缓存:☆☆

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值