All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.weicoder.redis.cache.RedisCache Maven / Gradle / Ivy

There is a newer version: 3.6.2
Show newest version
package com.weicoder.redis.cache;

import com.weicoder.common.util.U;
import com.weicoder.common.lang.W.C;
import com.weicoder.common.lang.W.L;
import com.weicoder.common.lang.W.M;

import java.util.List;
import java.util.Map;

import com.weicoder.cache.BeanCache;
import com.weicoder.json.J;
import com.weicoder.common.thread.T;
import com.weicoder.redis.Redis;
import com.weicoder.redis.factory.RedisFactory;
import com.weicoder.redis.params.RedisParams;

/**
 * 使用Redis存储缓存
 * 
 * @author wudi
 */
@SuppressWarnings("unchecked")
public class RedisCache extends BeanCache {
	/**
	 * 构建一个新的RedisCache
	 * 
	 * @param    值类型
	 * @param redis Redis名
	 * @param key   缓存主key 在hset里的key
	 * @return 一个新的RedisCache
	 */
	public static  RedisCache build(String redis, String key, Class cls) {
		return build(RedisFactory.getRedis(redis), key, cls);
	}

	/**
	 * 构建一个新的RedisCache
	 * 
	 * @param    值类型
	 * @param redis Redis名
	 * @param key   缓存主key 在hset里的key
	 * @param load  是否加载全部缓存
	 * @return 一个新的RedisCache
	 */
	public static  RedisCache build(String redis, String key, Class cls, boolean fill) {
		return build(RedisFactory.getRedis(redis), key, cls, fill);
	}

	/**
	 * 构建一个新的RedisCache
	 * 
	 * @param    值类型
	 * @param redis Redis名
	 * @param key   缓存主key 在hset里的key
	 * @param cls   要缓存的类
	 * @return 一个新的RedisCache
	 */
	public static  RedisCache build(Redis redis, String key, Class cls) {
		return build(redis, key, cls, RedisParams.getCacheFill(redis.name()));
	}

	/**
	 * 构建一个新的RedisCache
	 * 
	 * @param    值类型
	 * @param redis Redis名
	 * @param key   缓存主key 在hset里的key
	 * @param cls   要缓存的类
	 * @param fill  是否加载全部缓存
	 * @return 一个新的RedisCache
	 */
	public static  RedisCache build(Redis redis, String key, Class cls, boolean fill) {
		return new RedisCache<>(redis, key, cls, fill);
	}

	// redis
	protected Redis					redis;
	// redis channel
	protected String				put;
	protected String				remove;
	protected String				push;
	// 是否基础类型
	protected boolean				base;
	// 基础类型传递分隔符
	protected final static String	SEPA	= "||";

	/**
	 * 获得当前redis缓存使用的redis
	 * 
	 * @return
	 */
	public Redis redis() {
		return redis;
	}

	/**
	 * 加入缓存
	 * 
	 * @param rkey  键
	 * @param value 值
	 */
	public V put(K key, V value) {
		super.put(key, value);
		String k = C.toString(key);
		String v = base ? C.toString(value) : J.toJson(value);
		redis.multi(r -> {
			r.hset(this.name, k, v);
			r.lpush(push, k);
			r.publish(put, base ? k + SEPA + v : v);
		});
		return value;
	}

	/**
	 * 删除缓存
	 */
	public void remove(K key) {
		super.remove(key);
		redis.multi(r -> {
			r.hdel(this.name, C.toString(key));
			r.publish(remove, C.toString(key));
		});
	}

	/**
	 * 加载所以缓存
	 */
	public void fill() {
		redis.hgetAll(name).forEach((k, v) -> super.put(J.toBean(v, val)));
	}

	/**
	 * 获得所有redis里的缓存 注意是使用hgetAll获取redis 如果用本地缓存使用values()
	 * 
	 * @return 所有缓存
	 */
	public Map all() {
		Map map = M.map();
		redis.hgetAll(name).forEach((k, v) -> map.put((K) C.to(k, key), J.toBean(v, val)));
		return map;
	}

	/**
	 * 如果本地数量与redis数量一致返回super.map() 不一致返回all()
	 * 
	 * @return 缓存list
	 */
	public Map map() {
		return size() == len() ? super.map() : all();
	}

	/**
	 * 如果本地数量与redis数量一致返回values() 不一致返回all().values()
	 * 
	 * @return 缓存list
	 */
	public List list() {
		return size() == len() ? values() : L.list(all().values());
	}

	/**
	 * 获得redis里的数量
	 * 
	 * @return
	 */
	public long len() {
		return redis.hlen(name);
	}

	@Override
	public void fill(List vals) {
		vals.forEach(v -> {
			K k = key(v);
			cache.put(k, v);
			redis.hset(name, k, v);
		});
	}

	/**
	 * 构造
	 * 
	 * @param redis 使用的redis
	 * @param key   保存redis的键
	 * @param cls   缓存值Class
	 * @param load  是否加载全部缓存
	 */
	protected RedisCache(Redis redis, String key, Class cls, boolean fill) {
		super(key, cls, r -> cls == null || U.C.isBaseType(cls) ? (V) C.to(redis.hget(key, C.toString(r)), cls)
				: J.toBean(redis.hget(key, C.toString(r)), cls));
		// 获得redis
		this.val = cls;
		this.redis = redis;
		this.base = cls == null || U.C.isBaseType(cls);
		this.put = key + "_put";
		this.remove = key + "_remove";
		this.push = key + "_push";
		// 是否加载所以缓存
		if (fill)
			fill();
		// 使用Redis发布订阅来更新缓存
		T.E.pool(RedisParams.PREFIX).execute(() -> {
			this.redis.subscribe((c, m) -> {
				if (put.equals(c))
					// 更新
					if (base) {
						String[] t = U.S.split(m, SEPA);
						cache.put((K) C.to(t[0], this.key), (V) C.to(t[1], this.val));
					} else {
						V v = J.toBean(m, this.val);
						cache.put(key(v), v);
					}
				else if (remove.equals(c))
					// 删除
					super.remove((K) C.to(m, this.key));
			}, put, remove);
		});
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy