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

让ibatis 支持 memcached

阅读更多
ibatis 不支持Memcached ,只支持第三方的oscache.
所以看了一下缓存模块源码,觉得的很好扩展,于是就实现了一下,不知是否合理还请大家扳砖

SqlMapConfiguration 中新建别名

registerDefaultTypeAliases方法中添加

typeHandlerFactory.putTypeAlias("MEMCACHED", MemcachedCacheController.class.getName());



public interface OtherCacheHelper<T> {
         //初始化第三方缓存
	public void initCache() ;
         //获取第三方缓存句柄
           //client分布式中相关主机
	public T getCacheHandler(String client) ;
}



采用xmemcached连接memcached server
public class MemcacheCacheHelper implements OtherCacheHelper<XMemcachedClient> {

	private static XMemcachedClient xmc;

	public MemcacheCacheHelper() {
		initCache();
	}

	@Override
	public XMemcachedClient getCacheHandler(String client) {
		// TODO Auto-generated method stub
		return xmc;
	}

	@Override
	public void initCache() {
		// TODO Auto-generated method stub
		try {
			xmc = new XMemcachedClient("192.168.1.105", 11212);
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

}


memcached管理类
public class MemcachedCacheController implements CacheController {

	private XMemcachedClient cacheHandler = null;

	//keyList 管理key
         private LinkedList<String> keyList = null;

	private int cacheSize;

	public MemcachedCacheController() {
		cacheSize = 100;
		keyList = new LinkedList<String>();
	}


	@Override
	public void flush(CacheModel cacheModel) {
		// TODO Auto-generated method stub
		try {
			for (String key : keyList) {
				cacheHandler.delete(key);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		keyList.clear();
	}

	@Override
	public Object getObject(CacheModel cacheModel, Object key) {
		// TODO Auto-generated method stub
		String ckey = getKey(cacheModel, key);

		
		try {
			return cacheHandler.get(ckey);
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	@Override
	public void putObject(CacheModel cacheModel, Object key, Object object) {
		String ckey = getKey(cacheModel, key);
		// TODO Auto-generated method stub
		keyList.addLast(ckey);
		
		try {
			cacheHandler.add(ckey,0,object);
			if (keyList.size() > cacheSize) {
				String first = keyList.removeFirst();
				cacheHandler.delete(first);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	@Override
	public Object removeObject(CacheModel cacheModel, Object key) {
		// TODO Auto-generated method stub
		String ckey = getKey(cacheModel, key);
		try {
			if (keyList.contains(ckey)) {
				return cacheHandler.delete(ckey);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

		return null;
	}

	@Override
	public void setProperties(Properties props) {
		// TODO Auto-generated method stub
		String size = props.getProperty("cache-size");
		if (size == null) {
			size = props.getProperty("size");
		}
		if (size != null) {
			cacheSize = Integer.parseInt(size);
		}
		//获取缓存帮助类
                  String cacheHelpObject = props.getProperty("cache-helper");
		
                  String cacheclient = props.getProperty("cache-client");
		if (cacheHelpObject != null) {
			try {
				Class clazz = Resources.classForName(cacheHelpObject);
				Object obj = Resources.instantiate(clazz);
				if (obj instanceof MemcacheCacheHelper) {
					cacheHandler = ((MemcacheCacheHelper) obj)
							.getCacheHandler(cacheclient);
				}
			} catch (Exception e) {
				e.printStackTrace();
			}

		}

	}

//因为我认为ibaits 的缓存key 太长了,所以采用再hash的方法,再加上的缓存ID
	private String getKey(CacheModel cacheModel, Object cacheKey) {
		String key = cacheKey.toString();
		int keyhash = key.hashCode();
		String cacheId = cacheModel.getId();
		return cacheId + "_" + keyhash;
	}

}


对应实体XML设置
<cacheModel type="MEMCACHED" id="account-cache" serialize="true">
    <flushInterval hours="12"/>
    <property name="size" value="10" />
    <property name="cache-helper" value="com.ibatis.sqlmap.engine.cache.memcached.MemcacheCacheHelper" />
    <property name="cache-client" value="mclient0" />
  </cacheModel>





分享到:
评论
19 楼 snowolf 2012-03-08  
记得曾经实现过iBatis+EhCache,实现了一个iBatis的Controller,获得EhCache支持。Memcached是否可参考呢?
18 楼 nirvana_blanks 2010-10-29  
<div class="quote_title"> 写道</div>
<div class="quote_div"> //因为我认为ibaits 的缓存key 太长了,所以采用再hash的方法,再加上的缓存ID  <br>  private String getKey(CacheModel cacheModel, Object cacheKey) {  <br>         String key = cacheKey.toString();  <br>        int keyhash = key.hashCode();  <br>         String cacheId = cacheModel.getId();  <br>         return cacheId + "_" + keyhash;  <br>    }  </div>
 
<p>不用这样吧,xmemcached会对key进行hash的。</p>
17 楼 myreligion 2010-06-22  
itstarting 写道
不可能这样玩吧,可以看看oscache的整合实现
如果真提供这样的扩展机制,也太不可思议了。

ibatis的cache和序列化方法好像都是固定的,不改代码没法改.很恶心的设计。
16 楼 pan_java 2010-06-21  
tedeyang 写道
pan_java 写道
超级潜水艇 写道
楼主最后几句话会不会有问题?
引用

   //因为我认为ibaits 的缓存key 太长了,所以采用再hash的方法,再加上的缓存ID 
    private String getKey(CacheModel cacheModel, Object cacheKey) { 
        String key = cacheKey.toString(); 
        int keyhash = key.hashCode(); 
        String cacheId = cacheModel.getId(); 
        return cacheId + "_" + keyhash; 
    } 

有可能会存在多个sql键值对应成一个hashcode的情况。如果加上cacheModel的id一样的话。那么就会造成不同的sql(hash值一样)对应了一个相同的缓存,
比如select * from user这个语句对应了一个缓存。假设另一个sql:select * from product这个语句相好(我是假设)和前一个的sql语句有了相同的hash值。那么此语句(select * from product)从缓存取回来的将是select * from user的缓存。显然这样就有问题了吧?

两个的SQL对应不同的缓存ID啊!
我采用的这个方案,并不算完美。希望大家指点.

很有用的思路,
我考虑的是直接在DAO或service层做拦截,和楼主遇到的问题一样,关键点就是key的生成算法。
楼主用hash恐怕不行,因为cacheModel可能会公用,而且同一个sql还有参数的差异,会有冲突的。
还是md5可靠。
打算采用Spring AOP来实现,不过以前有个Spring module项目提供一个通用cache层,很久没更新了。
楼主现在有没有什么最新的进展?


其实直接在DAO或service层做拦截不用修改ibatis源码.
如果你应用缓存只是单一的对象的话。可以用对象的id作为key。
如果多个不同类型缓存的话,可以用对象标识 + 对象id 作缓存key,不用什么md5
15 楼 treemap 2010-06-17  
看看 ,不错啊
14 楼 tedeyang 2010-06-16  
pan_java 写道
超级潜水艇 写道
楼主最后几句话会不会有问题?
引用

   //因为我认为ibaits 的缓存key 太长了,所以采用再hash的方法,再加上的缓存ID 
    private String getKey(CacheModel cacheModel, Object cacheKey) { 
        String key = cacheKey.toString(); 
        int keyhash = key.hashCode(); 
        String cacheId = cacheModel.getId(); 
        return cacheId + "_" + keyhash; 
    } 

有可能会存在多个sql键值对应成一个hashcode的情况。如果加上cacheModel的id一样的话。那么就会造成不同的sql(hash值一样)对应了一个相同的缓存,
比如select * from user这个语句对应了一个缓存。假设另一个sql:select * from product这个语句相好(我是假设)和前一个的sql语句有了相同的hash值。那么此语句(select * from product)从缓存取回来的将是select * from user的缓存。显然这样就有问题了吧?

两个的SQL对应不同的缓存ID啊!
我采用的这个方案,并不算完美。希望大家指点.

很有用的思路,
我考虑的是直接在DAO或service层做拦截,和楼主遇到的问题一样,关键点就是key的生成算法。
楼主用hash恐怕不行,因为cacheModel可能会公用,而且同一个sql还有参数的差异,会有冲突的。
还是md5可靠。
打算采用Spring AOP来实现,不过以前有个Spring module项目提供一个通用cache层,很久没更新了。
楼主现在有没有什么最新的进展?
13 楼 pan_java 2010-02-02  
超级潜水艇 写道
楼主最后几句话会不会有问题?
引用

   //因为我认为ibaits 的缓存key 太长了,所以采用再hash的方法,再加上的缓存ID 
    private String getKey(CacheModel cacheModel, Object cacheKey) { 
        String key = cacheKey.toString(); 
        int keyhash = key.hashCode(); 
        String cacheId = cacheModel.getId(); 
        return cacheId + "_" + keyhash; 
    } 

有可能会存在多个sql键值对应成一个hashcode的情况。如果加上cacheModel的id一样的话。那么就会造成不同的sql(hash值一样)对应了一个相同的缓存,
比如select * from user这个语句对应了一个缓存。假设另一个sql:select * from product这个语句相好(我是假设)和前一个的sql语句有了相同的hash值。那么此语句(select * from product)从缓存取回来的将是select * from user的缓存。显然这样就有问题了吧?

两个的SQL对应不同的缓存ID啊!
我采用的这个方案,并不算完美。希望大家指点.
12 楼 超级潜水艇 2010-02-02  
楼主最后几句话会不会有问题?
引用

   //因为我认为ibaits 的缓存key 太长了,所以采用再hash的方法,再加上的缓存ID 
    private String getKey(CacheModel cacheModel, Object cacheKey) { 
        String key = cacheKey.toString(); 
        int keyhash = key.hashCode(); 
        String cacheId = cacheModel.getId(); 
        return cacheId + "_" + keyhash; 
    } 

有可能会存在多个sql键值对应成一个hashcode的情况。如果加上cacheModel的id一样的话。那么就会造成不同的sql(hash值一样)对应了一个相同的缓存,
比如select * from user这个语句对应了一个缓存。假设另一个sql:select * from product这个语句相好(我是假设)和前一个的sql语句有了相同的hash值。那么此语句(select * from product)从缓存取回来的将是select * from user的缓存。显然这样就有问题了吧?
11 楼 pan_java 2009-12-29  
typeHandlerFactory.putTypeAlias("MEMCACHED", MemcachedCacheController.class.getName()); 

对就是这里,我肯定试过!
10 楼 eyeqq 2009-12-29  
也不会要重新打包啊。
只有
typeHandlerFactory.putTypeAlias("MEMCACHED", MemcachedCacheController.class.getName()); 
这里是需要修改原码的。
其它的都是直接扩展。
楼主有没试过直接用类名的使用方式?应该可以吧。
9 楼 pan_java 2009-12-29  
eyeqq 写道
这位兄弟不错啊,起码公布了自己具体实现。
附件里头是某博士的学术文章,我感觉你比他写的好。
博士让ibatis支持memcached思路跟你不一样,提供给你参照参照。

谢谢,我的实现方式最大缺点就是要修改源码,
不过有人提出使用插件的方式.
我想通过类似struts2插件方式去实现,但是一直没有好的思路.
8 楼 eyeqq 2009-12-29  
这位兄弟不错啊,起码公布了自己具体实现。
附件里头是某博士的学术文章,我感觉你比他写的好。
博士让ibatis支持memcached思路跟你不一样,提供给你参照参照。
7 楼 pan_java 2009-11-24  
itstarting 写道
不可能这样玩吧,可以看看oscache的整合实现
如果真提供这样的扩展机制,也太不可思议了。

那你有什么高见!
6 楼 itstarting 2009-11-24  
不可能这样玩吧,可以看看oscache的整合实现
如果真提供这样的扩展机制,也太不可思议了。
5 楼 SteveGY 2009-11-24  
哦,这个有用~~~,thanks
4 楼 pan_java 2009-11-23  
aimer311 写道
mem的key不支持空格,长度不能超过78个字符,这个要重新测试下。
我用的key
	private String getIdentityKey(Object key){
		String result;
		DateFormat df = new SimpleDateFormat("yyyyMMddHHmmsss");
		String tmp = df.format(new Date());
		result = MD5.getMD5(tmp.getBytes()) + MD5.getMD5(key.toString().getBytes());
		return result;
	}

有没有类似插件机制的实现方法,lz的方式还是需要重新编译源码。

建议不错!插件机制易于扩展!
3 楼 aimer311 2009-11-23  
mem的key不支持空格,长度不能超过78个字符,这个要重新测试下。
我用的key
	private String getIdentityKey(Object key){
		String result;
		DateFormat df = new SimpleDateFormat("yyyyMMddHHmmsss");
		String tmp = df.format(new Date());
		result = MD5.getMD5(tmp.getBytes()) + MD5.getMD5(key.toString().getBytes());
		return result;
	}

有没有类似插件机制的实现方法,lz的方式还是需要重新编译源码。
2 楼 redwave 2009-11-23  
怎么扩展ibatis 支持Memcached 希望楼主能给出代码
难道需要修改源码然后再编译之后拷贝到jar中吗
1 楼 pan_java 2009-11-23  
怎么没有人批一下!

相关推荐

    ibatis_with_memcached

    3. **分布式支持**:Memcached支持分布式部署,可以应对高并发场景,保证服务的稳定性和可扩展性。 4. **缓存策略**:Ibatis与Memcached集成后,可以设置不同的缓存策略,如LRU(最近最少使用)、FIFO(先进先出)等...

    ibatis memcached 整合 源码 文档

    在IT行业中,数据库缓存是提高应用程序性能的关键技术之一,Memcached是一款广泛使用的分布式内存对象缓存系统,而iBatis则是一个优秀的SQL映射框架。本文将详细讲解如何将iBatis与Memcached整合,以及相关的源码...

    ibatis memcached

    标题中的“ibatis memcached”指的是将MyBatis(原名iBATIS)这个流行的Java持久层框架与Memcached这个分布式内存对象缓存系统相结合,实现数据的高效缓存管理。这种集成允许开发者将MyBatis的二级缓存功能扩展到...

    asp.net mvc2.0+Spring.net1.3+Ibatis.net+memcached文档

    asp.net mvc2.0+Spring.net1.3+Ibatis.net+memcached的帮助,里面有spring.net和asp.netMVC的教程和一个贯穿案例。希望对大家有所帮助。绝对值这个分。

    spring-mybatis-memcached.zip_Memcached java_annotation_mybatis_m

    因为 mybatis-memcached 不支持 MyBatis2(iBatis),只能用在 MyBatis3 里。但是因为有的项目还跑在 MyBatis2 版本上,所以也做一个例子。 mm-mybatis3-memcached 使用了 mybatis-memcached 。因为 simple-spring-...

    ibatis与memchaced使用说明

    - `java_memcached-release_2.0.1.jar`: 提供了memcached客户端支持。 - `apache-commo-lang.jar`: 通用工具类,可能用于某些辅助功能。 ##### 初始化配置: ```xml &lt;bean class="com.ibatis.sqlmap.engine.cache....

    Maven+spring+ibatis+struts2.0+MQ+Memcached 项目构建

    【标题】"Maven+Spring+Ibatis+Struts2.0+MQ+Memcached 项目构建"涉及了多个核心的Java开发技术和框架,这些技术的集成应用在现代企业级应用开发中非常常见。让我们逐一深入理解这些技术及其在项目中的作用。 1. ...

    Ibatis.net 分页

    2. **动态SQL**:Ibatis.NET支持动态SQL,可以直接在XML映射文件中编写分页查询语句。利用`&lt;if&gt;`标签检查参数是否为空,然后在查询中加入ORDER BY和LIMIT子句。 ```xml SELECT * FROM Users WHERE 1=1 != null...

    基于 Spring和 Memcached的 iBATIS二级 缓存的研究与应用 (2009年)

    高性能是J2EE应用程序追求的目标,在特定硬件基础上,数据...在对 iBATIS的缓存支持情况进行了介绍和研究的基础上,并结合Spring框架和iBATIS,使用Memcached对iBATIS二级缓存进行了新的实现,使应用的性能得到了很大的提升.

    Memcache+spring+ibatis例子,包含单纯memcache例子

    包含最简单的memcache的使用,测试类MemCached.java; 在此基础上增加了memcahce和spring的整合,顺便使用了ibati,测试类SpringMemcacheTest.java 代码简洁,适合研究,参考

    JavaEye论坛热点月报 总第5期

    11. **Ibatis2支持Annotation**:Ibatis是一个流行的持久层框架,报告中介绍了如何让Ibatis2支持注解,使代码更简洁,配置更直观。 12. **内存泄漏分析**:通过Java的垃圾收集(GC)日志,开发者可以分析内存泄漏问题...

    大数据功能模块概要设计.doc

    NoSQL数据库如mongodb、hadoop、hive、hbase、memcached、redis等用于非结构化数据处理。 3.3 **底层开发框架**:Java服务端开发推荐使用struts2 + spring3+ ibatis(mybatis),前台WEB开发框架建议使用JS框架如...

    大数据功能模块概要设计-V1.1Word版.docx

    - **数据库**:关系型数据库如Oracle、MySQL,以及NoSQL数据库如MongoDB、Hadoop、Hive、HBase、Memcached、Redis,Oracle要求10g以上版本。 - **开发框架**:Java服务端推荐Struts2+Spring3+iBatis或MyBatis,...

    第三方缓存整合mybatis.rar

    4. **配置MyBatis缓存**:MyBatis支持自定义缓存实现,我们需要创建一个实现了`org.apache.ibatis.cache.Cache`接口的类,这个类将负责与Redis交互,进行数据的存取。在MyBatis的配置文件中,将这个自定义缓存类注册...

    Java软件开发工程师面试题宝典.pdf

    3. **Spring MVC与Struts MVC**:两者都是用于构建MVC架构的应用框架,Spring MVC更现代且灵活,支持依赖注入,而Struts则相对老旧但社区支持广泛。了解它们的差异有助于选择合适的开发工具。 4. **Spring和iBatis*...

    AfinalDemo

    Afinal是一款轻量级的Java ORM(对象关系映射)框架,它的设计目标是简化数据库操作,让开发者能更专注于业务逻辑,而不是繁琐的数据访问层实现。Afinal借鉴了iBatis的一些优秀特性,同时也引入了自己的创新,比如...

Global site tag (gtag.js) - Google Analytics