mybatis缓存机制
2016-11-23 11:37
337 查看
mybatis正如大多数持久层框架一样,缓存提供一级缓存和二级缓存。如hibernate
先说说mybatis一级缓存
用过hibernate的人应该了解,hibernate一级缓存的作用域是session。而session的生命周期很短,所以hibernate的一级缓存生命期也很短。
mybatis的一级缓存与hibernate一样,
具体举例如下:
AboutDto.Java
[java] view
plain copy
public class AboutDto{
private String areacode;
private String areaname;
private String parentcode;
private String memo;
public AboutDto()
{}
public AboutDto(String areacode, String areaname, String parentcode) {
this.areacode = areacode;
this.areaname = areaname;
this.parentcode = parentcode;
}
public String getAreacode() {
return areacode;
}
public void setAreacode(String areacode) {
this.areacode = areacode == null ? null : areacode.trim();
}
public String getAreaname() {
return areaname;
}
public void setAreaname(String areaname) {
this.areaname = areaname == null ? null : areaname.trim();
}
public String getParentcode() {
return parentcode;
}
public void setParentcode(String parentcode) {
this.parentcode = parentcode == null ? null : parentcode.trim();
}
public String getMemo() {
return memo;
}
public void setMemo(String memo) {
this.memo = memo == null ? null : memo.trim();
}
AboutDtoMapper.java
[java] view
plain copy
public interface AboutDtoMapper {
AboutDto selectByPrimaryKey(@Param("areacode")String areacode);
}
在这里,我只定义了一个根据主键查询的接口方法
AboutDtoMapper.xml
[html] view
plain copy
<?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="test.dao.AboutDtoMapper">
<resultMap id="BaseResultMap" type="test.model.AboutDto">
<id column="AREACODE" jdbcType="VARCHAR" property="areacode" />
<result column="AREANAME" jdbcType="VARCHAR" property="areaname" />
<result column="PARENTCODE" jdbcType="VARCHAR" property="parentcode" />
<result column="MEMO" jdbcType="VARCHAR" property="memo" />
</resultMap>
<sql id="Base_Column_List">
AREACODE, AREANAME, PARENTCODE, MEMO
</sql>
<select id="selectByPrimaryKey" parameterType="map" resultMap="BaseResultMap" >
select * from SYS_AREAINFO
where AREACODE = #{areacode}
</select>
</mapper>
测试
[java] view
plain copy
public static void main(String[] args)
{
AboutDtoMapper mapper = session.getMapper(AboutDtoMapper.class);
AboutDto dto = mapper.selectByPrimaryKey("pqgl01");
System.out.println(dto.getAreaname());
<span style="color:#FF0000;">session.commit();//1</span>
AboutDto dto2 = mapper.selectByPrimaryKey("pqgl01");
System.out.println(dto2.getAreaname());
}
测试结果
[html] view
plain copy
DEBUG - Created connection 7791465.
DEBUG - ooo Connection Opened
DEBUG - ==> Executing: select * from SYS_AREAINFO where AREACODE = ?
DEBUG - ==> Parameters: pqgl01(String)
DEBUG - <== Columns: AREACODE, AREANAME, PARENTCODE, MEMO
DEBUG - <== Row: pqgl01, 龙泉驿, pqgl20, null
龙泉驿
DEBUG - ==> Executing: select * from SYS_AREAINFO where AREACODE = ?
DEBUG - ==> Parameters: pqgl01(String)
DEBUG - <== Columns: AREACODE, AREANAME, PARENTCODE, MEMO
DEBUG - <== Row: pqgl01, 龙泉驿, pqgl20, null
龙泉驿
mybatis默认一级缓存是开启的,所以这里就不贴mybatis-config.xml中代码了。
上面测试中,当session提交后,控制台打印显示,程序执行了两次查询数据库的操作。当我们屏蔽掉1处commit代码,再看控制台结果
[html] view
plain copy
DEBUG - PooledDataSource forcefully closed/removed all connections.
DEBUG - PooledDataSource forcefully closed/removed all connections.
DEBUG - PooledDataSource forcefully closed/removed all connections.
DEBUG - PooledDataSource forcefully closed/removed all connections.
DEBUG - Created connection 7791465.
DEBUG - ooo Connection Opened
DEBUG - ==> Executing: select * from SYS_AREAINFO where AREACODE = ?
DEBUG - ==> Parameters: pqgl01(String)
DEBUG - <== Columns: AREACODE, AREANAME, PARENTCODE, MEMO
DEBUG - <== Row: pqgl01, 龙泉驿, pqgl20, null
龙泉驿
龙泉驿
这里只执行了一次查询数据库操作。
由此可见,mybatis的一级缓存作用域只存在于session。
下面说说mybatis的二级缓存。
mybatis的二级缓存
我们先测试不开启mybatis的二级缓存。
测试代码
[java] view
plain copy
public static void main(String args[])
{
session1 = sqlSessionFactory.openSession();
session2 = sqlSessionFactory.openSession();
AboutDtoMapper mapper1 = session1.getMapper(AboutDtoMapper.class);
AboutDtoMapper mapper2 = session2.getMapper(AboutDtoMapper.class);
AboutDto dto = mapper1.selectByPrimaryKey("pqgl01");
System.out.println(dto.getAreaname());
session1.commit();
AboutDto dto2 = mapper2.selectByPrimaryKey("pqgl01");
System.out.println(dto2.getAreaname());
session2.commit();
}
这里我们定义了两个session,分别查询主键为pggl01对象。控制台输出结果
[html] view
plain copy
DEBUG - Created connection 21021313.
DEBUG - ooo Connection Opened
DEBUG - ==> Executing: select * from SYS_AREAINFO where AREACODE = ?
DEBUG - ==> Parameters: pqgl01(String)
DEBUG - <== Columns: AREACODE, AREANAME, PARENTCODE, MEMO
DEBUG - <== Row: pqgl01, 龙泉驿, pqgl20, null
龙泉驿
DEBUG - ==> Executing: select * from SYS_AREAINFO where AREACODE = ?
DEBUG - ==> Parameters: pqgl01(String)
DEBUG - <== Columns: AREACODE, AREANAME, PARENTCODE, MEMO
DEBUG - <== Row: pqgl01, 龙泉驿, pqgl20, null
龙泉驿
这里mybatis与数据库交互了两次,说明mybatis目前尚未开启二级缓存。需要我们手动开启。
在这里我用的
slf4j-api-1.6.1.jar
mybatis-ehcache-1.0.3.jar
ehcache-core-2.6.9.jar
配置AboutDtoMapper.xml
[html] view
plain copy
<?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="test.dao.AboutDtoMapper">
<span style="color:#FF0000;"><cache type="org.mybatis.caches.ehcache.EhcacheCache"/></span> <!--这里指明缓存类型-->
<resultMap id="BaseResultMap" type="test.model.AboutDto">
<id column="AREACODE" jdbcType="VARCHAR" property="areacode" />
<result column="AREANAME" jdbcType="VARCHAR" property="areaname" />
<result column="PARENTCODE" jdbcType="VARCHAR" property="parentcode" />
<result column="MEMO" jdbcType="VARCHAR" property="memo" />
</resultMap>
<sql id="Base_Column_List">
AREACODE, AREANAME, PARENTCODE, MEMO
</sql>
<select id="selectByPrimaryKey" parameterType="map" resultMap="BaseResultMap" >
select * from SYS_AREAINFO
where AREACODE = #{areacode}
</select>
</mapper>
ehcache.xml
[html] view
plain copy
<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd" updateCheck="true" monitoring="autodetect" dynamicConfig="true">
<diskStore path="d:\test" />
<defaultCache
maxElementsInMemory="10000"
maxElementsOnDisk="100000000"
eternal="false"
overflowToDisk="true"
timeToIdleSeconds="300"
timeToLiveSeconds="600"
diskPersistent="false"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU"
/>
<!--
name:Cache的唯一标识
maxElementsInMemory:内存中最大缓存对象数
maxElementsOnDisk:磁盘中最大缓存对象数,若是0表示无穷大
eternal:Element是否永久有效,一但设置了,timeout将不起作用
overflowToDisk:配置此属性,当内存中Element数量达到maxElementsInMemory时,Ehcache将会Element写到磁盘中
timeToIdleSeconds:设置Element在失效前的允许闲置时间。仅当element不是永久有效时使用,可选属性,默认值是0,也就是可闲置时间无穷大
timeToLiveSeconds:设置Element在失效前允许存活时间。最大时间介于创建时间和失效时间之间。仅当element不是永久有效时使用,默认是0.,也就是element存活时间无穷大
diskPersistent:是否缓存虚拟机重启期数据
diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔,默认是120秒
diskSpoolBufferSizeMB:这个参数设置DiskStore(磁盘缓存)的缓存区大小。默认是30MB。每个Cache都应该有自己的一个缓冲区
memoryStoreEvictionPolicy:当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略去清理内存。默认策略是LRU(最近最少使用)。你可以设置为FIFO(先进先出)或是LFU(较少使用)
-->
</ehcache>
特别需要说明的是,当开启mybatis的二级缓存时,Mapper的实体对象必须实现可序列化接口,否则会异常
[html] view
plain copy
Exception in thread "main" org.apache.ibatis.exceptions.PersistenceException:
### Error committing transaction. Cause: org.apache.ibatis.cache.CacheException: Error serializing object. Cause: java.io.NotSerializableException: test.model.AboutDto
### Cause: org.apache.ibatis.cache.CacheException: Error serializing object. Cause: java.io.NotSerializableException: test.model.AboutDto
at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:8)
at org.apache.ibatis.session.defaults.DefaultSqlSession.commit(DefaultSqlSession.java:127)
at org.apache.ibatis.session.defaults.DefaultSqlSession.commit(DefaultSqlSession.java:119)
at Test.main(Test.java:60)
Caused by: org.apache.ibatis.cache.CacheException: Error serializing object. Cause: java.io.NotSerializableException: test.model.AboutDto
at org.apache.ibatis.cache.decorators.SerializedCache.serialize(SerializedCache.java:67)
at org.apache.ibatis.cache.decorators.SerializedCache.putObject(SerializedCache.java:27)
at org.apache.ibatis.cache.decorators.LoggingCache.putObject(LoggingCache.java:30)
at org.apache.ibatis.cache.decorators.SynchronizedCache.putObject(SynchronizedCache.java:31)
at org.apache.ibatis.cache.decorators.TransactionalCache$AddEntry.commit(TransactionalCache.java:96)
at org.apache.ibatis.cache.decorators.TransactionalCache.commit(TransactionalCache.java:66)
at org.apache.ibatis.cache.TransactionalCacheManager.commit(TransactionalCacheManager.java:22)
at org.apache.ibatis.executor.CachingExecutor.commit(CachingExecutor.java:81)
at org.apache.ibatis.session.defaults.DefaultSqlSession.commit(DefaultSqlSession.java:124)
... 2 more
Caused by: java.io.NotSerializableException: test.model.AboutDto
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1156)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:326)
at java.util.ArrayList.writeObject(ArrayList.java:570)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:945)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1461)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1392)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1150)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:326)
at org.apache.ibatis.cache.decorators.SerializedCache.serialize(SerializedCache.java:62)
... 10 more
测试结果
[html] view
plain copy
DEBUG - ooo Connection Opened
DEBUG - Cache Hit Ratio [test.dao.AboutDtoMapper]: 0.0
DEBUG - ==> Executing: select * from SYS_AREAINFO where AREACODE = ?
DEBUG - ==> Parameters: pqgl01(String)
DEBUG - <== Columns: AREACODE, AREANAME, PARENTCODE, MEMO
DEBUG - <== Row: pqgl01, 龙泉驿, pqgl20, null
龙泉驿
DEBUG - put added 0 on heap
龙泉驿
DEBUG - Cache Hit Ratio [test.dao.AboutDtoMapper]: 0.5
DEBUG - fault removed 0 from heap
DEBUG - fault added 0 on disk
测试结果表明,只操作一次数据库
最后,补充一点,手动控制mybatis的一级缓存是否开启方式,在mybatis-config.xml文件中加
[html] view
plain copy
<settings>
<setting name="cacheEnabled" value="true"/>
</settings>
如有错误之处,请及时说明。
顶1
踩
先说说mybatis一级缓存
用过hibernate的人应该了解,hibernate一级缓存的作用域是session。而session的生命周期很短,所以hibernate的一级缓存生命期也很短。
mybatis的一级缓存与hibernate一样,
基于PerpetualCache 的 HashMap本地缓存,作用域也是session,一旦session close或则flush后,其中的缓存数据也将清空。
具体举例如下:
AboutDto.Java
[java] view
plain copy
public class AboutDto{
private String areacode;
private String areaname;
private String parentcode;
private String memo;
public AboutDto()
{}
public AboutDto(String areacode, String areaname, String parentcode) {
this.areacode = areacode;
this.areaname = areaname;
this.parentcode = parentcode;
}
public String getAreacode() {
return areacode;
}
public void setAreacode(String areacode) {
this.areacode = areacode == null ? null : areacode.trim();
}
public String getAreaname() {
return areaname;
}
public void setAreaname(String areaname) {
this.areaname = areaname == null ? null : areaname.trim();
}
public String getParentcode() {
return parentcode;
}
public void setParentcode(String parentcode) {
this.parentcode = parentcode == null ? null : parentcode.trim();
}
public String getMemo() {
return memo;
}
public void setMemo(String memo) {
this.memo = memo == null ? null : memo.trim();
}
AboutDtoMapper.java
[java] view
plain copy
public interface AboutDtoMapper {
AboutDto selectByPrimaryKey(@Param("areacode")String areacode);
}
在这里,我只定义了一个根据主键查询的接口方法
AboutDtoMapper.xml
[html] view
plain copy
<?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="test.dao.AboutDtoMapper">
<resultMap id="BaseResultMap" type="test.model.AboutDto">
<id column="AREACODE" jdbcType="VARCHAR" property="areacode" />
<result column="AREANAME" jdbcType="VARCHAR" property="areaname" />
<result column="PARENTCODE" jdbcType="VARCHAR" property="parentcode" />
<result column="MEMO" jdbcType="VARCHAR" property="memo" />
</resultMap>
<sql id="Base_Column_List">
AREACODE, AREANAME, PARENTCODE, MEMO
</sql>
<select id="selectByPrimaryKey" parameterType="map" resultMap="BaseResultMap" >
select * from SYS_AREAINFO
where AREACODE = #{areacode}
</select>
</mapper>
测试
[java] view
plain copy
public static void main(String[] args)
{
AboutDtoMapper mapper = session.getMapper(AboutDtoMapper.class);
AboutDto dto = mapper.selectByPrimaryKey("pqgl01");
System.out.println(dto.getAreaname());
<span style="color:#FF0000;">session.commit();//1</span>
AboutDto dto2 = mapper.selectByPrimaryKey("pqgl01");
System.out.println(dto2.getAreaname());
}
测试结果
[html] view
plain copy
DEBUG - Created connection 7791465.
DEBUG - ooo Connection Opened
DEBUG - ==> Executing: select * from SYS_AREAINFO where AREACODE = ?
DEBUG - ==> Parameters: pqgl01(String)
DEBUG - <== Columns: AREACODE, AREANAME, PARENTCODE, MEMO
DEBUG - <== Row: pqgl01, 龙泉驿, pqgl20, null
龙泉驿
DEBUG - ==> Executing: select * from SYS_AREAINFO where AREACODE = ?
DEBUG - ==> Parameters: pqgl01(String)
DEBUG - <== Columns: AREACODE, AREANAME, PARENTCODE, MEMO
DEBUG - <== Row: pqgl01, 龙泉驿, pqgl20, null
龙泉驿
mybatis默认一级缓存是开启的,所以这里就不贴mybatis-config.xml中代码了。
上面测试中,当session提交后,控制台打印显示,程序执行了两次查询数据库的操作。当我们屏蔽掉1处commit代码,再看控制台结果
[html] view
plain copy
DEBUG - PooledDataSource forcefully closed/removed all connections.
DEBUG - PooledDataSource forcefully closed/removed all connections.
DEBUG - PooledDataSource forcefully closed/removed all connections.
DEBUG - PooledDataSource forcefully closed/removed all connections.
DEBUG - Created connection 7791465.
DEBUG - ooo Connection Opened
DEBUG - ==> Executing: select * from SYS_AREAINFO where AREACODE = ?
DEBUG - ==> Parameters: pqgl01(String)
DEBUG - <== Columns: AREACODE, AREANAME, PARENTCODE, MEMO
DEBUG - <== Row: pqgl01, 龙泉驿, pqgl20, null
龙泉驿
龙泉驿
这里只执行了一次查询数据库操作。
由此可见,mybatis的一级缓存作用域只存在于session。
下面说说mybatis的二级缓存。
mybatis的二级缓存
与一级缓存其机制相同,默认也是采用 PerpetualCache,HashMap存储,不同在于其存储作用域为 Mapper(Namespace),并且可自定义存储源,如 Ehcache。
我们先测试不开启mybatis的二级缓存。
测试代码
[java] view
plain copy
public static void main(String args[])
{
session1 = sqlSessionFactory.openSession();
session2 = sqlSessionFactory.openSession();
AboutDtoMapper mapper1 = session1.getMapper(AboutDtoMapper.class);
AboutDtoMapper mapper2 = session2.getMapper(AboutDtoMapper.class);
AboutDto dto = mapper1.selectByPrimaryKey("pqgl01");
System.out.println(dto.getAreaname());
session1.commit();
AboutDto dto2 = mapper2.selectByPrimaryKey("pqgl01");
System.out.println(dto2.getAreaname());
session2.commit();
}
这里我们定义了两个session,分别查询主键为pggl01对象。控制台输出结果
[html] view
plain copy
DEBUG - Created connection 21021313.
DEBUG - ooo Connection Opened
DEBUG - ==> Executing: select * from SYS_AREAINFO where AREACODE = ?
DEBUG - ==> Parameters: pqgl01(String)
DEBUG - <== Columns: AREACODE, AREANAME, PARENTCODE, MEMO
DEBUG - <== Row: pqgl01, 龙泉驿, pqgl20, null
龙泉驿
DEBUG - ==> Executing: select * from SYS_AREAINFO where AREACODE = ?
DEBUG - ==> Parameters: pqgl01(String)
DEBUG - <== Columns: AREACODE, AREANAME, PARENTCODE, MEMO
DEBUG - <== Row: pqgl01, 龙泉驿, pqgl20, null
龙泉驿
这里mybatis与数据库交互了两次,说明mybatis目前尚未开启二级缓存。需要我们手动开启。
在这里我用的
Ehcache。需要注意的是,这里需要加入几个jar包
slf4j-api-1.6.1.jar
mybatis-ehcache-1.0.3.jar
ehcache-core-2.6.9.jar
配置AboutDtoMapper.xml
[html] view
plain copy
<?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="test.dao.AboutDtoMapper">
<span style="color:#FF0000;"><cache type="org.mybatis.caches.ehcache.EhcacheCache"/></span> <!--这里指明缓存类型-->
<resultMap id="BaseResultMap" type="test.model.AboutDto">
<id column="AREACODE" jdbcType="VARCHAR" property="areacode" />
<result column="AREANAME" jdbcType="VARCHAR" property="areaname" />
<result column="PARENTCODE" jdbcType="VARCHAR" property="parentcode" />
<result column="MEMO" jdbcType="VARCHAR" property="memo" />
</resultMap>
<sql id="Base_Column_List">
AREACODE, AREANAME, PARENTCODE, MEMO
</sql>
<select id="selectByPrimaryKey" parameterType="map" resultMap="BaseResultMap" >
select * from SYS_AREAINFO
where AREACODE = #{areacode}
</select>
</mapper>
ehcache.xml
[html] view
plain copy
<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd" updateCheck="true" monitoring="autodetect" dynamicConfig="true">
<diskStore path="d:\test" />
<defaultCache
maxElementsInMemory="10000"
maxElementsOnDisk="100000000"
eternal="false"
overflowToDisk="true"
timeToIdleSeconds="300"
timeToLiveSeconds="600"
diskPersistent="false"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU"
/>
<!--
name:Cache的唯一标识
maxElementsInMemory:内存中最大缓存对象数
maxElementsOnDisk:磁盘中最大缓存对象数,若是0表示无穷大
eternal:Element是否永久有效,一但设置了,timeout将不起作用
overflowToDisk:配置此属性,当内存中Element数量达到maxElementsInMemory时,Ehcache将会Element写到磁盘中
timeToIdleSeconds:设置Element在失效前的允许闲置时间。仅当element不是永久有效时使用,可选属性,默认值是0,也就是可闲置时间无穷大
timeToLiveSeconds:设置Element在失效前允许存活时间。最大时间介于创建时间和失效时间之间。仅当element不是永久有效时使用,默认是0.,也就是element存活时间无穷大
diskPersistent:是否缓存虚拟机重启期数据
diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔,默认是120秒
diskSpoolBufferSizeMB:这个参数设置DiskStore(磁盘缓存)的缓存区大小。默认是30MB。每个Cache都应该有自己的一个缓冲区
memoryStoreEvictionPolicy:当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略去清理内存。默认策略是LRU(最近最少使用)。你可以设置为FIFO(先进先出)或是LFU(较少使用)
-->
</ehcache>
特别需要说明的是,当开启mybatis的二级缓存时,Mapper的实体对象必须实现可序列化接口,否则会异常
[html] view
plain copy
Exception in thread "main" org.apache.ibatis.exceptions.PersistenceException:
### Error committing transaction. Cause: org.apache.ibatis.cache.CacheException: Error serializing object. Cause: java.io.NotSerializableException: test.model.AboutDto
### Cause: org.apache.ibatis.cache.CacheException: Error serializing object. Cause: java.io.NotSerializableException: test.model.AboutDto
at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:8)
at org.apache.ibatis.session.defaults.DefaultSqlSession.commit(DefaultSqlSession.java:127)
at org.apache.ibatis.session.defaults.DefaultSqlSession.commit(DefaultSqlSession.java:119)
at Test.main(Test.java:60)
Caused by: org.apache.ibatis.cache.CacheException: Error serializing object. Cause: java.io.NotSerializableException: test.model.AboutDto
at org.apache.ibatis.cache.decorators.SerializedCache.serialize(SerializedCache.java:67)
at org.apache.ibatis.cache.decorators.SerializedCache.putObject(SerializedCache.java:27)
at org.apache.ibatis.cache.decorators.LoggingCache.putObject(LoggingCache.java:30)
at org.apache.ibatis.cache.decorators.SynchronizedCache.putObject(SynchronizedCache.java:31)
at org.apache.ibatis.cache.decorators.TransactionalCache$AddEntry.commit(TransactionalCache.java:96)
at org.apache.ibatis.cache.decorators.TransactionalCache.commit(TransactionalCache.java:66)
at org.apache.ibatis.cache.TransactionalCacheManager.commit(TransactionalCacheManager.java:22)
at org.apache.ibatis.executor.CachingExecutor.commit(CachingExecutor.java:81)
at org.apache.ibatis.session.defaults.DefaultSqlSession.commit(DefaultSqlSession.java:124)
... 2 more
Caused by: java.io.NotSerializableException: test.model.AboutDto
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1156)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:326)
at java.util.ArrayList.writeObject(ArrayList.java:570)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:945)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1461)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1392)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1150)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:326)
at org.apache.ibatis.cache.decorators.SerializedCache.serialize(SerializedCache.java:62)
... 10 more
测试结果
[html] view
plain copy
DEBUG - ooo Connection Opened
DEBUG - Cache Hit Ratio [test.dao.AboutDtoMapper]: 0.0
DEBUG - ==> Executing: select * from SYS_AREAINFO where AREACODE = ?
DEBUG - ==> Parameters: pqgl01(String)
DEBUG - <== Columns: AREACODE, AREANAME, PARENTCODE, MEMO
DEBUG - <== Row: pqgl01, 龙泉驿, pqgl20, null
龙泉驿
DEBUG - put added 0 on heap
龙泉驿
DEBUG - Cache Hit Ratio [test.dao.AboutDtoMapper]: 0.5
DEBUG - fault removed 0 from heap
DEBUG - fault added 0 on disk
测试结果表明,只操作一次数据库
最后,补充一点,手动控制mybatis的一级缓存是否开启方式,在mybatis-config.xml文件中加
[html] view
plain copy
<settings>
<setting name="cacheEnabled" value="true"/>
</settings>
如有错误之处,请及时说明。
顶1
踩
相关文章推荐
- mybatis的缓存机制
- Mybatis缓存机制
- mybatis缓存机制
- Mybatis缓存机制
- Mybatis缓存机制
- MyBatis 缓存机制深度解剖 / 自定义二级缓存
- 《深入理解mybatis原理》 MyBatis缓存机制的设计与实现
- 《深入理解mybatis原理》 MyBatis缓存机制的设计与实现
- 《深入理解mybatis原理》 MyBatis缓存机制的设计与实现
- mybatis缓存机制
- 《深入理解mybatis原理(六)》 MyBatis缓存机制的设计与实现如何细粒度地控制你的MyBatis二级缓存
- mybatis缓存机制
- mybatis缓存机制
- mybatis的缓存机制(一级缓存二级缓存和刷新缓存)和mybatis整合ehcache
- MyBatis 缓存机制深度解剖 / 自定义二级缓存
- 关于MyBatis的缓存机制
- MyBatis 缓存机制深度解剖
- mybatis缓存机制详解(一)——Cache
- mybatis缓存机制
- mybatis缓存机制