论坛首页 Java企业应用论坛

memcached的使用(二)hibernate cache provider

浏览 13025 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2006-10-19  
实现hibernate的cache provider,让hibernate使用memcached缓存。
这里比较简单,由于memcached的SockIOPool已经在(一)中spring中初始化了,这里就不考虑pool的初始化,直接获得MemCachedClient使用即可。
然后配置给hibernate<prop key="hibernate.cache.provider_class">×××</prop>

附代码:
/**
 * @author Marc
 *
 */
public class MemcachedProvider implements CacheProvider {
	public Cache buildCache(String name, Properties properties) throws CacheException {
		return new MemCache(name);
	}

	public boolean isMinimalPutsEnabledByDefault() {
		return false;
	}

	public long nextTimestamp() {
		return Timestamper.next();
	}

	public void start(Properties properties) throws CacheException {
	}

	public void stop() {
	}

}

/**
 * @author Marc
 * 
 */
public class MemCache implements Cache {
	private static final Log log = LogFactory.getLog(MemCache.class);

	private static final int SIXTY_THOUSAND_MS = 60000;

	MemCachedClient mc;
	String regionName;

	/**
	 * Creates a new Hibernate pluggable cache based on a cache name. <p/>
	 * 
	 * @param cache
	 *            The underlying EhCache instance to use.
	 */
	public MemCache(String regionName) {
		mc = new MemCachedClient();
		mc.setCompressEnable(false);
		this.regionName = regionName;
	}

	/**
	 * Gets a value of an element which matches the given key.
	 * 
	 * @param key
	 *            the key of the element to return.
	 * @return The value placed into the cache with an earlier put, or null if
	 *         not found or expired
	 * @throws CacheException
	 */
	public Object get(Object key) throws CacheException {
		if (log.isDebugEnabled()) {
			log.debug("key: " + key);
		}
		if (key == null) {
			return null;
		} else {
			Object rt = mc.get(key.toString());
			if (rt == null) {
				if (log.isDebugEnabled()) {
					log.debug("Element for " + key + " is null");
				}
				return null;
			} else {
				return rt;
			}
		}

	}

	public Object read(Object key) throws CacheException {
		return get(key);
	}

	/**
	 * Puts an object into the cache.
	 * 
	 * @param key
	 *            a key
	 * @param value
	 *            a value
	 * @throws CacheException
	 *             if the {@link CacheManager} is shutdown or another
	 *             {@link Exception} occurs.
	 */
	public void update(Object key, Object value) throws CacheException {
		put(key, value);
	}

	/**
	 * Puts an object into the cache.
	 * 
	 * @param key
	 *            a key
	 * @param value
	 *            a value
	 * @throws CacheException
	 *             if the {@link CacheManager} is shutdown or another
	 *             {@link Exception} occurs.
	 */
	public void put(Object key, Object value) throws CacheException {
		mc.set(key.toString(), value);
	}

	/**
	 * Removes the element which matches the key. <p/> If no element matches,
	 * nothing is removed and no Exception is thrown.
	 * 
	 * @param key
	 *            the key of the element to remove
	 * @throws CacheException
	 */
	public void remove(Object key) throws CacheException {
		mc.delete(key.toString());
	}

	/**
	 * Remove all elements in the cache, but leave the cache in a useable state.
	 * 
	 * @throws CacheException
	 */
	public void clear() throws CacheException {
		log.warn("cann't clear all items in memcached!");
		throw new CacheException("cann't clear all items in memcached!");
	}

	/**
	 * Remove the cache and make it unuseable.
	 * 
	 * @throws CacheException
	 */
	public void destroy() throws CacheException {

	}

	/**
	 * Calls to this method should perform there own synchronization. It is
	 * provided for distributed caches. Because EHCache is not distributed this
	 * method does nothing.
	 */
	public void lock(Object key) throws CacheException {
	}

	/**
	 * Calls to this method should perform there own synchronization. It is
	 * provided for distributed caches. Because EHCache is not distributed this
	 * method does nothing.
	 */
	public void unlock(Object key) throws CacheException {
	}

	/**
	 * Gets the next timestamp;
	 */
	public long nextTimestamp() {
		return Timestamper.next();
	}

	/**
	 * Returns the lock timeout for this cache.
	 */
	public int getTimeout() {
		// 60 second lock timeout
		return Timestamper.ONE_MS * SIXTY_THOUSAND_MS;
	}

	public String getRegionName() {
		return this.regionName;
	}

	/**
	 * Warning: This method can be very expensive to run. Allow approximately 1
	 * second per 1MB of entries. Running this method could create liveness
	 * problems because the object lock is held for a long period <p/>
	 * 
	 * @return the approximate size of memory ehcache is using for the
	 *         MemoryStore for this cache
	 */
	public long getSizeInMemory() {
		log.warn("cann't getSizeInMemory in memcached!");
		throw new CacheException("cann't getSizeInMemory in memcached!");
	}

	public long getElementCountInMemory() {
		log.warn("cann't getElementCountInMemory in memcached!");
		throw new CacheException("cann't getElementCountInMemory in memcached!");
	}

	public long getElementCountOnDisk() {
		log.warn("cann't getElementCountOnDisk in memcached!");
		throw new CacheException("cann't getElementCountOnDisk in memcached!");
	}

	public Map toMap() {
		log.warn("cann't toMap in memcached!");
		throw new CacheException("cann't toMap in memcached!");
	}

	public String toString() {
		return "MemCached(" + getRegionName() + ')';
	}

}
   发表时间:2006-10-19  
老兄您要挣分也别这样挣好不.
0 请登录后投票
   发表时间:2006-11-01  
这个cache provider有问题,如果楼主遇到了,并且解决了,那我就先不发解决方法了
0 请登录后投票
   发表时间:2007-01-19  
主要是有几个方法的Object key这个参数的使用问题。

做查询的时候,hibernate会将整个sql做为key,其中有空格(还有一些其他的字符,想不起来了)等等,会导致memcached出错。

所以,要取key的hashCode才行。但是为了避免某些字符串的hashCode相同,我是这样做的。


    
/**
     * 取key的hashCode做为memcached的key,避免key中的一些特殊符号导致memcached工作异常
     * @param key
     * @return hashCode后的key
     */
    private String encodeKey(Object key) {
        int hashCode = new HashCodeBuilder(-167198555, -754611037).append(String.valueOf(key)).append(getRegionName()).toHashCode();
        return String.valueOf(hashCode);
    }
0 请登录后投票
   发表时间:2007-01-19  
把这个encodeKey返回的结果传给MemCachedClient 的方法,就可以了
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics