MyBatis缓存

本文介绍了MyBatis中的一级缓存和二级缓存配置方法,并提供了具体示例,包括如何启用缓存、配置Ehcache及自定义缓存实现。

一:MyBatis的一级缓存默认是开启的,但是如果MyBatis和Spring搭配后,一级缓存失效,如果想用一级缓存,加上@Transactional就可以了。




二:二级缓存:


        在mybatis.xml中加入<setting name="cacheEnabled" value="true" />  在PersonDao.xml中加入<cache />


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC  
    "-//mybatis.org//DTD Config 3.0//EN"  
    "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
	<settings>
		<setting name="cacheEnabled" value="true" />
	</settings>
	<mappers>
		<mapper resource="com/we/dao/PersonDao.xml" />
	</mappers>
</configuration>


<?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.we.dao.PersonDao">
	<select id="get" parameterType="com.we.entry.Person" resultMap="result">
		select * from person WHERE id=#{id}
	</select>

	<resultMap type="com.we.entry.Person" id="result">
		<id column="id" property="id" />
		<result column="name" property="name" />
	</resultMap>

	<update id="updateById" parameterType="com.we.entry.Person">
		update person set
		name=#{name} where id=#{id}
	</update>
	<cache />
</mapper>


三:可以通过对比日志查看到缓存是否成功。如果不加<cache />和加则是以下两种


DEBUG 2016-08-29 20:08:09,499 org.mybatis.spring.SqlSessionUtils: Creating a new SqlSession
DEBUG 2016-08-29 20:08:09,499 org.mybatis.spring.SqlSessionUtils: SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@253d9f73] was not registered for synchronization because synchronization is not active
DEBUG 2016-08-29 20:08:09,499 org.apache.ibatis.cache.decorators.LoggingCache: Cache Hit Ratio [com.we.dao.PersonDao]: 0.75
DEBUG 2016-08-29 20:08:09,499 org.mybatis.spring.SqlSessionUtils: Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@253d9f73]





2
DEBUG 2016-08-29 20:05:25,212 org.mybatis.spring.SqlSessionUtils: Creating a new SqlSession
DEBUG 2016-08-29 20:05:25,212 org.mybatis.spring.SqlSessionUtils: SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@1941a8ff] was not registered for synchronization because synchronization is not active
DEBUG 2016-08-29 20:05:25,212 org.springframework.jdbc.datasource.DataSourceUtils: Fetching JDBC Connection from DataSource
DEBUG 2016-08-29 20:05:25,212 org.mybatis.spring.transaction.SpringManagedTransaction: JDBC Connection [com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl@2e1ef60] will not be managed by Spring
DEBUG 2016-08-29 20:05:25,212 org.apache.ibatis.logging.jdbc.BaseJdbcLogger: ==>  Preparing: select * from person WHERE id=? 
DEBUG 2016-08-29 20:05:25,212 org.apache.ibatis.logging.jdbc.BaseJdbcLogger: ==> Parameters: 1(Integer)
DEBUG 2016-08-29 20:05:25,228 org.apache.ibatis.logging.jdbc.BaseJdbcLogger: <==      Total: 1
DEBUG 2016-08-29 20:05:25,228 org.mybatis.spring.SqlSessionUtils: Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@1941a8ff]
DEBUG 2016-08-29 20:05:25,228 org.springframework.jdbc.datasource.DataSourceUtils: Returning JDBC Connection to DataSource
3






四 配置Ehcache:加入jar包

<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache-core</artifactId>
<version>2.6.11</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-ehcache</artifactId>
<version>1.0.0</version>
</dependency>
然后把上面的cacha换成下面两个的任意一个。可以看一下两个类的实现就可以发现,LoggingEhcache是对EhcacheCache的包装。(LoggingEhcache的构造方法)
     <cache type="org.mybatis.caches.ehcache.LoggingEhcache" />
     <cache type="org.mybatis.caches.ehcache.EhcacheCache"/> 



五:配置redis缓存  

MyBatis配置redis需要实现org.apache.ibatis.cache.Cache接口,然后把四中的类改为自己写的类就行了。例子待续。




注意:在cache标签中还有好几个属性需要挖掘。比如说eviction是配置缓存策略。还有

<cache type="org.mybatis.caches.ehcache.LoggingEhcache"  eviction="缓存策略" blocking="" flushInterval="" readOnly="" size="" />

### 三级标题:MyBatis 缓存机制的工作原理 MyBatis 提供了两种级别的缓存机制:一级缓存和二级缓存,分别适用于不同的使用场景,并通过特定的数据结构实现查询结果的存储与复用。 一级缓存是 SqlSession 级别的缓存,默认情况下是开启的。每个 SqlSession 都会维护一个本地缓存(基于 HashMap 实现),用于存储该 SqlSession 中执行过的查询结果。在同一个 SqlSession 中,如果执行相同的查询语句,则 MyBatis 会直接从缓存中获取数据,而不会再次访问数据库[^3]。当执行插入、更新或删除操作时,MyBatis 会自动清空当前 SqlSession 的一级缓存,以确保数据的一致性[^1]。 二级缓存是 Mapper(namespace)级别的缓存,多个 SqlSession 可以共享同一个 Mapper 的二级缓存。这意味着跨 SqlSession 的查询可以复用缓存数据,前提是这些查询属于相同的 Mapper 命名空间。二级缓存需要显式配置,可以通过接口注解方式实现,例如使用 `@CacheNamespace` 注解来启用指定 Mapper 接口的二级缓存功能[^2]。 以下是一个使用注解方式配置 MyBatis 二级缓存的示例: ```java @CacheNamespace public interface UserMapper { User getUserById(int id); } ``` ### 三级标题:MyBatis 缓存的使用注意事项 尽管缓存机制可以显著提升数据库查询性能,但在实际应用中需要注意以下几点。 首先,一级缓存的作用范围仅限于当前 SqlSession,不同 SqlSession 之间的缓存数据互不影响。因此,在涉及多个 SqlSession 或事务隔离级别较高的场景下,不能依赖一级缓存保证数据一致性[^4]。 其次,二级缓存虽然支持跨 SqlSession 共享数据,但其默认实现并不具备线程安全特性。在并发访问频繁的环境中,建议引入第三方缓存组件(如 Ehcache 或 Redis)以提高稳定性和可扩展性。此外,二级缓存的生命周期独立于 SqlSession,即使关闭或清除 SqlSession,缓存数据依然存在,因此必须谨慎管理缓存更新策略,避免出现脏读问题[^1]。 最后,由于缓存机制的存在,某些情况下可能会导致查询结果与数据库中的最新数据不一致。为了解决这一问题,可以在执行写操作后手动刷新缓存,或者通过配置合理的缓存失效时间来控制数据同步的粒度。同时,应避免对频繁更新的数据使用缓存,以免因频繁清空缓存而抵消性能优化效果[^3]。 ### 三级标题:相关代码示例 以下是一个展示 MyBatis 一级缓存行为的简单示例。在这个例子中,两次调用相同的查询方法将只触发一次数据库访问: ```java public class UserService { @Autowired private SqlSession sqlSession; public void testCache() { UserMapper mapper = sqlSession.getMapper(UserMapper.class); // 第一次查询,结果从数据库中获取 User user1 = mapper.getUserById(1); // 第二次查询相同的记录,结果从一级缓存中获取,不再访问数据库 User user2 = mapper.getUserById(1); } } ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值