Redis复杂数据更新管理的实现(二)

174 阅读4分钟

「这是我参与2022首次更文挑战的第16天,活动详情查看:2022首次更文挑战

1、问题引入

​ 当我们遇到复杂结构的redis数据更新时,如何将原始数据存到数据库后组装同步到redis?然后,在项目中还有一个需求就是有些数据入库后,需要通过MQ发送到其他服务。所以就将其整合成了一个公共的功能,只需要通过配置、写好自己的处理器即可,这样就去除了重复、繁琐的代码。下面就先为大家介绍下具体实现。

2、复杂结构Redis数据更新的实现

//根据配置信息更新缓存
@Component
public class CacheUpdateComponent { 

    @Resource(name = "rabbitTemplate")
    private RabbitTemplate rabbitTemplate;

    /**
     * 判断sqlid是否在缓存配置中, 如果存在,则进行缓存更新操作
     * @param execonfig 执行对sqlid集合
     * @param params    参数
     * @throws KPromptException
     */
    public void judgeSqlIdExistByConfig(SqlExecute execonfig, Map<String, Object> params) throws  PromptException {
        try {
            judgeSqlIdExistByConfig(execonfig.getSqlids(), params);
        } catch (Exception e) {
            logger.error("更新缓存失败:" + e.getMessage(), e);
            throw new PromptException("更新缓存失败:" + e.getMessage());
        }
    } 

	public void judgeSqlIdExistByConfig(List<String> execonfigSqlIds, Map<String, Object> params) throws KPromptException {
        boolean flag;
        for (String exeSqlId:execonfigSqlIds) {
            try {
                flag = CacheUtil.existsKey(RedisKeyNameEntity.CACHE_CONFIG_NAME + exeSqlId, true);
                // 非缓存配置页面进行的操作
                if (flag) {
                    CacheConfigInfo configInfo = JSONObject.parseObject(SysBeans.getCacheAble().getCache(RedisKeyNameEntity.CACHE_CONFIG_NAME + exeSqlId, true), CacheConfigInfo.class);
                    // 对redis进行更新
                    if (CacheConfigStatusEntity.REDIS_STATUS_YES.equals(configInfo.getRedisStatus())){
                    	String redisValueType = configInfo.getRedisValueType();
                    	String redisPrefixHooks = configInfo.getRedisPrefixHooks();
                    	if(null != redisPrefixHooks && !redisPrefixHooks.isEmpty()){
                    		params = (Map<String, Object>) KInvoke.invokeDistributedHander(redisPrefixHooks, params);
                    	}
                    	if(null != configInfo.getRedisNonCacheKey() && !configInfo.getRedisNonCacheKey().isEmpty()) {
                    		if(RedisValueTypeEntity.HASH.equals(redisValueType)) {
                    			SysBeans.getCacheAble().setMap(CacheUtil.cacheKeyHandler(configInfo.getRedisParamKey(), configInfo.getRedisPrefix(), params), true, CacheUtil.cacheMapValHandler(CacheUtil.cacheValHandler(configInfo.getRedisNonCacheKey(), params)));
                    		}else {
                    			SysBeans.getCacheAble().setCache(CacheUtil.cacheKeyHandler(configInfo.getRedisParamKey(), configInfo.getRedisPrefix(), params), JSON.toJSONString(CacheUtil.cacheValHandler(configInfo.getRedisNonCacheKey(), params)), true);
                    		}
                    	}else {
                    		if(RedisValueTypeEntity.HASH.equals(redisValueType)) {
                    			SysBeans.getCacheAble().setMap(CacheUtil.cacheKeyHandler(configInfo.getRedisParamKey(), configInfo.getRedisPrefix(), params), true, CacheUtil.cacheMapValHandler(params));
                    		}else {
                    			SysBeans.getCacheAble().setCache(CacheUtil.cacheKeyHandler(configInfo.getRedisParamKey(), configInfo.getRedisPrefix(), params), JSON.toJSONString(params), true);
                    		}
                    	}
                    	String redisBehindHooks = configInfo.getRedisBehindHooks();
                        if(null != redisBehindHooks && !redisBehindHooks.isEmpty()) {
                        	KInvoke.invokeTechnologiesHander(redisBehindHooks, params);
                        }
                    }
                    // 对mq进行更新
                    if (CacheConfigStatusEntity.MQ_STATUS_YES.equals(configInfo.getMqStatus())){
                    	//获取前置hook函数
                    	String mqPrefixHooks = configInfo.getMqPrefixHooks();
                    	if(null != mqPrefixHooks && !mqPrefixHooks.isEmpty()){
                    		params = (Map<String, Object>) KInvoke.invokeDistributedHander(mqPrefixHooks, params);
                    	}
                        if (null != configInfo.getMqRoutingKey() && !configInfo.getMqRoutingKey().isEmpty()) {
                            rabbitTemplate.convertAndSend(configInfo.getMqName(), configInfo.getMqRoutingKey(), params);
                        }else {
                            rabbitTemplate.convertAndSend(configInfo.getMqName(), params);
                        }
                        String mqBehindHooks = configInfo.getMqBehindHooks();
                        if(null != mqBehindHooks && !mqBehindHooks.isEmpty()) {
                        	KInvoke.invokeTechnologiesHander(mqBehindHooks, params);
                        }
                    }
                }
            } catch (Exception e) {
                logger.error("更新缓存失败:" + e.getMessage(), e);
                throw new PromptException("更新缓存失败:" + e.getMessage());
            }
        }
    }

}

//对于redis缓存之前的钩子函数的执行,是通过反射完成的,这里也为大家分享下反射工具类 
public class InvokeUtil {
	
	/**
	 * 反射处理器(无入参、无返回)
	 * @param invokeConfig	反射配置		格式:报名.类名.方法名
	 * @return
	 * @throws Exception
	 */
	public static void invokeTechnologiesHander(String invokeConfig) throws Exception {
    	String[] hC = invokeConfig.split("\\.");
    	if(1 > hC.length) {
    		throw new KPromptException("反射配置错误,配置信息为:[" + invokeConfig + "]");
    	}
		String methodName = hC[hC.length-1];
		String className = invokeConfig.substring(0, invokeConfig.indexOf(methodName)-1);
		Object obj = getInvokeObj(className);
		Method method = getInvokeMethod(methodName, obj.getClass());
        method.invoke(obj);
    }
	
	/**
	 * 反射处理器(无入参、无返回)
	 * @param invokeConfig	反射配置		格式:报名.类名 + 分隔符 + 方法名
	 * @param separator		分隔符
	 * @return
	 * @throws Exception
	 */
	public static void invokeTechnologiesHander(String invokeConfig, String separator) throws Exception {
    	String[] hC = invokeConfig.split("\\" + separator);
    	if(1 > hC.length) {
    		throw new KPromptException("反射配置错误,配置信息为:[" + invokeConfig + "]");
    	}
		String methodName = hC[hC.length-1];
		String className = invokeConfig.substring(0, invokeConfig.indexOf(methodName)-1);
		Object obj = getInvokeObj(className);
		Method method = getInvokeMethod(methodName, obj.getClass());
        method.invoke(obj);
    }
	
	/**
	 * 反射处理器(有入参、无返回)
	 * @param invokeConfig	反射配置		格式:报名.类名.方法名
	 * @param args			参数
	 * @return
	 * @throws Exception
	 */
	public static void invokeTechnologiesHander(String invokeConfig, Object... args) throws Exception {
    	String[] hC = invokeConfig.split("\\.");
    	if(1 > hC.length) {
    		throw new KPromptException("反射配置错误,配置信息为:[" + invokeConfig + "]");
    	}
		String methodName = hC[hC.length-1];
		String className = invokeConfig.substring(0, invokeConfig.indexOf(methodName)-1);
		Object obj = getInvokeObj(className);
		Method method = getInvokeMethod(methodName, obj.getClass(), objToClassArr(args));
        method.invoke(obj, args);
    }
	
	/**
	 * 反射处理器(有入参、无返回)
	 * @param invokeConfig	反射配置		格式:报名.类名 + 分隔符 + 方法名
	 * @param separator		分隔符
	 * @param args			参数
	 * @return
	 * @throws Exception
	 */
	public static void invokeTechnologiesHander(String invokeConfig, String separator, Object... args) throws Exception {
    	String[] hC = invokeConfig.split("\\" + separator);
    	if(1 > hC.length) {
    		throw new KPromptException("反射配置错误,配置信息为:[" + invokeConfig + "]");
    	}
		String methodName = hC[hC.length-1];
		String className = invokeConfig.substring(0, invokeConfig.indexOf(methodName)-1);
		Object obj = getInvokeObj(className);
		Method method = getInvokeMethod(methodName, obj.getClass(), objToClassArr(args));
		method.invoke(obj, args);
    }
	
	/**
	 * 反射处理器(无入参、有返回)
	 * @param invokeConfig	反射配置		格式:报名.类名.方法名
	 * @return
	 * @throws Exception
	 */
	public static Object invokeDistributedHander(String invokeConfig) throws Exception {
    	String[] hC = invokeConfig.split("\\.");
    	if(1 > hC.length) {
    		throw new KPromptException("反射配置错误,配置信息为:[" + invokeConfig + "]");
    	}
		String methodName = hC[hC.length-1];
		String className = invokeConfig.substring(0, invokeConfig.indexOf(methodName)-1);
		Object obj = getInvokeObj(className);
		Method method = getInvokeMethod(methodName, obj.getClass());
        return method.invoke(obj);
    }
	
	/**
	 * 反射处理器(无入参、有返回)
	 * @param invokeConfig	反射配置		格式:报名.类名 + 分隔符 + 方法名
	 * @param separator		分隔符
	 * @return
	 * @throws Exception
	 */
	public static Object invokeDistributedHander(String invokeConfig, String separator) throws Exception {
    	String[] hC = invokeConfig.split("\\" + separator);
    	if(1 > hC.length) {
    		throw new KPromptException("反射配置错误,配置信息为:[" + invokeConfig + "]");
    	}
		String methodName = hC[hC.length-1];
		String className = invokeConfig.substring(0, invokeConfig.indexOf(methodName)-1);
		Object obj = getInvokeObj(className);
		Method method = getInvokeMethod(methodName, obj.getClass());
        return method.invoke(obj);
    }
	
	/**
	 * 反射处理器(有入参、有返回)
	 * @param invokeConfig	反射配置		格式:包名.类名.方法名
	 * @param args			参数
	 * @return
	 * @throws Exception
	 */
	public static Object invokeDistributedHander(String invokeConfig, Object... args) throws Exception {
    	String[] hC = invokeConfig.split("\\.");
    	if(1 > hC.length) {
    		throw new KPromptException("反射配置错误,配置信息为:[" + invokeConfig + "]");
    	}
		String methodName = hC[hC.length-1];
		String className = invokeConfig.substring(0, invokeConfig.indexOf(methodName)-1);
		Object obj = getInvokeObj(className);
		Method method = getInvokeMethod(methodName, obj.getClass(), objToClassArr(args));
        return method.invoke(obj, args);
    }
	
	/**
	 * 反射处理器(有入参、有返回)
	 * @param invokeConfig	反射配置		格式:包名.类名 + 分隔符 + 方法名
	 * @param separator		分隔符
	 * @param args			参数
	 * @return
	 * @throws Exception
	 */
	public static Object invokeDistributedHander(String invokeConfig, String separator, Object... args) throws Exception {
    	String[] hC = invokeConfig.split("\\" + separator);
    	if(1 > hC.length) {
    		throw new PromptException("反射配置错误,配置信息为:[" + invokeConfig + "]");
    	}
		String methodName = hC[hC.length-1];
		String className = invokeConfig.substring(0, invokeConfig.indexOf(methodName)-1);
		Object obj = getInvokeObj(className);
		Method method = getInvokeMethod(methodName, obj.getClass(), objToClassArr(args));
        return method.invoke(obj, args);
    }
	
	/**
	 * 获取反射(无入参)方法
	 * @param methodName	方法名称
	 * @param cls			反射类 
	 */
	@SuppressWarnings({ "unchecked", "rawtypes" })
	public static Method getInvokeMethod(String methodName, Class cls) throws Exception {
    	return cls.getDeclaredMethod(methodName);
    }
	
	/**
	 * 获取反射(有入参)方法
	 * @param methodName	方法名称
	 * @param cls			反射类
	 * @param paramClass	参数类
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings({ "unchecked", "rawtypes" })
	public static Method getInvokeMethod(String methodName, Class cls, Class<?>... paramClass) throws Exception {
    	return cls.getDeclaredMethod(methodName, paramClass);
    }
	
	/**
	 * 获取返回类实例(对象) 
	 */
	@SuppressWarnings({ "unchecked", "rawtypes" })
	public static Object getInvokeObj(String className) throws Exception {
		Class cls = Class.forName(className);
    	return cls.getConstructor().newInstance(); 
    }
	
	/**
	 * 
	 * @param args
	 * @return
	 */
	@SuppressWarnings("rawtypes")
	private static Class[] objToClassArr(Object... args) {
		Class[] classs = new Class[args.length];
		for(int i = 0; i < args.length; i++) {
			classs[i] = args[i].getClass();
		}
		return classs;
	}
	
}

好了、本期就先介绍到这里,有什么需要交流的,大家可以随时私信我。😊