`
QiuQiu0034
  • 浏览: 121748 次
  • 性别: Icon_minigender_1
  • 来自: 郑州
社区版块
存档分类
最新评论

Mybatis入门实例(二)——添加ehcache缓存支持

阅读更多

接上回: Mybatis入门实例(一),地址http://qiuqiu0034.iteye.com/blog/1157768 

本帖用的数据库和上面帖子中的数据库相同

 

为了提高MyBatis的性能,有时候我们需要加入缓存支持,目前用的比较多的缓存莫过于ehcache缓存了,ehcache性能强大,而且位各种应用都提供了解决方案,在此我们主要是做查询缓存,提高查询的效率.

 

在Mybatis的官网上把集成ehcache的文档下载下来看了看,说的太简单了,对于新手很难理解,而且里面说的也不是很清楚,经过一番折腾,终于将ehcache加入了.

 

官网上提供了一个MyBatis-ehcache.jar的包用于整合ehcache缓存,文档中还说明需要一个ehcache-core.jar的包,除了这两个包之外有几个包也是必须的,官方并没有说明,以下是需要加入的所有和ehcache相关的包:

1.ehcache-core-2.4.4.jar

2.mybatis-ehcache-1.0.0.jar

3.slf4j-api-1.6.1.jar

4.slf4j-log4j12-1.6.2.jar

 

除此之外还有mybatis的jar包,log4j,mysql驱动,这些大家应该都知道.

 

将上述包加入项目之后,新建一个文件名,该文件名必须为ehcache.xml,放在类路径下面,内容如下

 

<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:noNamespaceSchemaLocation="../bin/ehcache.xsd">
	<!--
	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(较少使用) 
	-->
	<defaultCache overflowToDisk="true" eternal="false"/>
	<diskStore path="D:/cache" />
	<!--
		<cache name="zzugxy" overflowToDisk="true" eternal="false"
		timeToIdleSeconds="300" timeToLiveSeconds="600" maxElementsInMemory="1000"
		maxElementsOnDisk="10" diskPersistent="true" diskExpiryThreadIntervalSeconds="300"
		diskSpoolBufferSizeMB="100" memoryStoreEvictionPolicy="LRU" />
	-->
</ehcache>

 

该文件是ehcache的配置文件,上面的注释已经说得很清楚了,这里我用的是默认的配置

至此ehcache已经配置好了,然后只需要在你想要缓存的mapper配置文件里面加入以下内容,该查询语句得到的结果将会被缓存

 

<?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.qiuqiu.dao.PersonDao">
	<!-- 以下两个<cache>标签二选一,第一个可以输出日志,第二个不输出日志 -->
	<cache type="org.mybatis.caches.ehcache.LoggingEhcache"/>
	<!-- <cache type="org.mybatis.caches.ehcache.EhcacheCache"/> -->
	
	<select id="selectUserById" parameterType="int" resultType="org.qiuqiu.vo.Person">
		select * from person where id=#{id} 
	</select>
</mapper>
 

这样就对这个mapper里面的各种结果进行了缓存.程序中不需要修改任何地方.

 

这个过程不复杂,也没什么难度,不过Mybatis的官方说的也太含糊了.附件下面有,需要的各种jar包已经包含.

分享到:
评论
9 楼 GONETHEN 2016-11-02  
怎样验证缓存成功?出现“Cache Hit Ratio [com.xxx.dao.TopicDao]: 0.25”证明成功了?




还有,他是如何实现判断缓存是否是最新,获取缓存还是获取数据库数据如何控制?mybatis-ehcache.jar做到的吗?
8 楼 dexuter 2014-06-23  
mikezdz 写道
缓存是用上了,不过这个例子表现的不够明显,我增加了几行重复查询和输出,效果应该就可以看出来了:
public class Test {

	public static void main(String[] args) {
		SqlSessionFactory factory = null;
		try {
			factory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsReader("Configuration.xml"));
		} catch (IOException e) {
			e.printStackTrace();
		}
		SqlSession sqlSession = factory.openSession();
		Person p = (Person) sqlSession.selectOne("com.qiuqiu.dao.PersonDao.selectUserById", 5);
		Person p1 = (Person) sqlSession.selectOne("com.qiuqiu.dao.PersonDao.selectUserById", 5);
		Person p2 = (Person) sqlSession.selectOne("com.qiuqiu.dao.PersonDao.selectUserById", 5);
		Person p3 = (Person) sqlSession.selectOne("com.qiuqiu.dao.PersonDao.selectUserById", 5);
		System.out.println("p:" + p.getName());
		System.out.println("p1:" + p1.getName());
		System.out.println("p2:" + p2.getName());
		System.out.println("p3:" + p3.getName());
		Person p4 = (Person) sqlSession.selectOne("com.qiuqiu.dao.PersonDao.selectUserById", 6);
		Person p5 = (Person) sqlSession.selectOne("com.qiuqiu.dao.PersonDao.selectUserById", 6);
		Person p6 = (Person) sqlSession.selectOne("com.qiuqiu.dao.PersonDao.selectUserById", 6);
		System.out.println("p4:" + p4.getName());
		System.out.println("p5:" + p5.getName());
		System.out.println("p6:" + p6.getName());

		Person p0 = (Person) sqlSession.selectOne("com.qiuqiu.dao.PersonDao.selectUserById", 5);
		Person p10 = (Person) sqlSession.selectOne("com.qiuqiu.dao.PersonDao.selectUserById", 5);
		Person p20 = (Person) sqlSession.selectOne("com.qiuqiu.dao.PersonDao.selectUserById", 5);
		Person p30 = (Person) sqlSession.selectOne("com.qiuqiu.dao.PersonDao.selectUserById", 5);
		System.out.println("p0:" + p0.getName());
		System.out.println("p10:" + p10.getName());
		System.out.println("p20:" + p20.getName());
		System.out.println("p30:" + p30.getName());
	}

}


你这个根本没用上ehcache的二级缓存吧,你这个用的session的一级缓存,mybatis一级缓存是默认开启的
7 楼 mikezdz 2013-08-15  
缓存是用上了,不过这个例子表现的不够明显,我增加了几行重复查询和输出,效果应该就可以看出来了:
public class Test {

	public static void main(String[] args) {
		SqlSessionFactory factory = null;
		try {
			factory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsReader("Configuration.xml"));
		} catch (IOException e) {
			e.printStackTrace();
		}
		SqlSession sqlSession = factory.openSession();
		Person p = (Person) sqlSession.selectOne("com.qiuqiu.dao.PersonDao.selectUserById", 5);
		Person p1 = (Person) sqlSession.selectOne("com.qiuqiu.dao.PersonDao.selectUserById", 5);
		Person p2 = (Person) sqlSession.selectOne("com.qiuqiu.dao.PersonDao.selectUserById", 5);
		Person p3 = (Person) sqlSession.selectOne("com.qiuqiu.dao.PersonDao.selectUserById", 5);
		System.out.println("p:" + p.getName());
		System.out.println("p1:" + p1.getName());
		System.out.println("p2:" + p2.getName());
		System.out.println("p3:" + p3.getName());
		Person p4 = (Person) sqlSession.selectOne("com.qiuqiu.dao.PersonDao.selectUserById", 6);
		Person p5 = (Person) sqlSession.selectOne("com.qiuqiu.dao.PersonDao.selectUserById", 6);
		Person p6 = (Person) sqlSession.selectOne("com.qiuqiu.dao.PersonDao.selectUserById", 6);
		System.out.println("p4:" + p4.getName());
		System.out.println("p5:" + p5.getName());
		System.out.println("p6:" + p6.getName());

		Person p0 = (Person) sqlSession.selectOne("com.qiuqiu.dao.PersonDao.selectUserById", 5);
		Person p10 = (Person) sqlSession.selectOne("com.qiuqiu.dao.PersonDao.selectUserById", 5);
		Person p20 = (Person) sqlSession.selectOne("com.qiuqiu.dao.PersonDao.selectUserById", 5);
		Person p30 = (Person) sqlSession.selectOne("com.qiuqiu.dao.PersonDao.selectUserById", 5);
		System.out.println("p0:" + p0.getName());
		System.out.println("p10:" + p10.getName());
		System.out.println("p20:" + p20.getName());
		System.out.println("p30:" + p30.getName());
	}

}

6 楼 xiaoxiaoming 2013-08-01  
感觉缓存没用上啊,,大家知道是怎么回事吗
5 楼 瑞木浩轩 2013-06-08  
digdata 写道
请问博主,我下载了您的实例后,运行时确不能命中缓存.
Cache Hit Ratio [com.qiuqiu.dao.PersonDao]: 0.0
多次执行都是命中率为0?

不知道您在测试的过程中是否也遇到?!


他的这个问题 不知道你搞定了没有!? 求教
4 楼 QiuQiu0034 2012-11-14  
digdata 写道
请问博主,我下载了您的实例后,运行时确不能命中缓存.
Cache Hit Ratio [com.qiuqiu.dao.PersonDao]: 0.0
多次执行都是命中率为0?

不知道您在测试的过程中是否也遇到?!

惭愧,这个我还真没有i仔细研究过,当时只是简单的配了起来可以运行
你不妨去Google Code上面看看源代码
3 楼 digdata 2012-11-13  
请问博主,我下载了您的实例后,运行时确不能命中缓存.
Cache Hit Ratio [com.qiuqiu.dao.PersonDao]: 0.0
多次执行都是命中率为0?

不知道您在测试的过程中是否也遇到?!
2 楼 manna_MM 2012-08-06  
好例子
1 楼 qqzhijun 2012-02-24  
谢啦,挺好的例子

相关推荐

Global site tag (gtag.js) - Google Analytics