Redis 在springBoot中的一个使用示例

在现系统中使用了一个字典表,更新或插入字典表需要做Redis缓存

    @Override
    @Cache(name = Constants.REDIS_PREFIX_DIC, desc = "变更字典后更新")
    public int editDict(DictEntity data) {
        int editCnt = -1;
        Date d = new Date();
        Integer dictId = data.getDictId();
        data.setUpdatedDate(d);
        if (dictId != null && dictId > 0) {
            editCnt = dictDao.updatedByPrimaryKeySelective(data);
        } else {
            data.setCreatedDate(d);
            data.setCreatedBy(data.getUpdatedBy());
            editCnt = dictDao.insertSelective(data);
            dictId = data.getDictId();
        }

        dictItemsDao.deleteByDictId(dictId);

        List<DictItemsEntity> list = new ArrayList<DictItemsEntity>();
        for (DictItemsEntity item : data.getItemsList()) {
            item.setDictId(dictId);
            list.add(item);
        }
        dictItemsDao.insertByList(list);
        return editCnt;
    }

 在此之上使用了一个@Catch的注解,这个注解是自己重写的,做Redis缓存的更新操作

@Catch注解:

package com.jn.baseservice.annotation;

import com.jn.baseservice.common.RedisConstant;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;


@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface Cache {


    /**
     * 缓存名
     *
     * @return
     */
    String name();

    /**
     * 更新范围
     *
     * @return
     */
    String range() default RedisConstant.RANGE_WHOLE;

    /**
     * 描述
     *
     * @return
     */
    String desc() default "";
}

 

其中以下两个注解可以去:https://www.cnblogs.com/peida/archive/2013/04/24/3036689.html 中查看

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})

 

之后使用一个切面,用于监听Redis更改缓存的操作:

package com.jn.ssr.superrescue.config;

import com.jn.baseservice.annotation.Cache;
import com.jn.baseservice.common.RedisConstant;
import com.jn.ssr.superrescue.cache.CacheFactory;
import com.jn.ssr.superrescue.cache.DictCache;
import com.jn.ssr.superrescue.tools.SpringConfigTool;

import lombok.extern.log4j.Log4j2;

import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;


@Aspect
@Component
@Log4j2
/**
 * 用于监听更改缓存的操作
 */
public class CacheAspect {
//切面范围:com.hhh.test.super下的service.impl 下所有的public开头的方法
    @Pointcut("execution(public * com.hhh.test.super.*.*.service.impl..*.*(..))")
    public void cacheCut() {
    }
//这个就是以上Redis的Catch的实现
    @AfterReturning(returning = "ret", pointcut = "cacheCut()", value = "@annotation(cache)")
    public void doAfterReturning(Object ret, Cache cache) throws Throwable {
        log.info("欢迎更改缓存:{}", ret);
        StopWatch watch = new StopWatch();
        watch.start(cache.name());
        CacheFactory factory = (CacheFactory) SpringConfigTool.getBean(DictCache.factoryMap.get(cache.name()));
        boolean result = cache.range().equals(RedisConstant.RANGE_WHOLE) ? factory.create().wholeRefresh() : factory.create().simpleRefresh(cache.name());
        watch.stop();
        log.info("缓存更新结果 {} taskName:{},耗时:{}ms,描述:{}", result, watch.getLastTaskName(), watch.getLastTaskTimeMillis(), cache.desc());
    }
}

 

调用了catchFactory:其中有一个create方法,返回一个CatcherUpdate对象:

package com.jn.ssr.superrescue.cache;


public interface CacheFactory {
    CacheUpdate create();
}

 

CatchUpdate中提供两个方法:

package com.jn.ssr.superrescue.cache;

public interface CacheUpdate {

    /**
     * vue调用组件
     */
    String key = "key";

    String label = "label";

    String id = "id";

    String parentId = "parentId";

    default boolean simpleRefresh(String name) {
        return true;
    }

    boolean wholeRefresh();
}

 

这个类的实现类是:

package com.jn.ssr.superrescue.cache.impl;

import com.jn.baseservice.common.Constants;
import com.jn.baseservice.common.RedisConstant;
import com.jn.baseservice.entity.dict.DictEntity;
import com.jn.baseservice.entity.dict.DictItemsEntity;
import com.jn.baseservice.utils.DateUtils;
import com.jn.baseservice.utils.RedisHandle;
import com.jn.ssr.superrescue.cache.CacheUpdate;
import connector.dict.DictService;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 字典类缓存
 *
 */
@Component
@Log4j2
public class DicCache implements CacheUpdate {

    @Autowired
    private RedisHandle redisHandle;

    @Autowired
    private DictService dictService;

    @Override
    public boolean simpleRefresh(String dicCode) {
        boolean result = true;
        try {
            DictEntity search = new DictEntity();
            search.setDictCode(dicCode);
            commonAdd(search);
        } catch (Exception e) {
            result = false;
            log.error("字典部分更新失败:", e);
        }
        return result;
    }

    @Override
    public boolean wholeRefresh() {
        boolean result = true;
        try {
            commonAdd(new DictEntity());
        } catch (Exception e) {
            result = false;
            log.error("字典全量更新失败:", e);
        }
        return result;
    }


    /**
     * 抽离公共部分
     *
     * @param search
     */
    private void commonAdd(DictEntity search) {
        search = new DictEntity();//需要全量更新 到REDIS_PREFIX_WEB_DIC
        log.info("添加基础数据字典");
        long start = System.currentTimeMillis();
        List<DictEntity> list = dictService.findBatchItems(search);
        Map<String, List<Map<String, String>>> dictMaps = new ConcurrentHashMap<>();
        for (DictEntity tmp : list) {
            String code = tmp.getDictCode();
            if (tmp.getCompanyId() != null && tmp.getCompanyId() > 0) {
                code += "_" + tmp.getCompanyId();
            }
            List<Map<String, String>> dictItems = new ArrayList<Map<String, String>>();
            List<DictItemsEntity> itemsList = tmp.getItemsList();
            Map<String, String> itemsMap = new LinkedHashMap<String, String>();
            for (DictItemsEntity item : itemsList) {
                Map<String, String> webMap = new LinkedHashMap<String, String>();
                webMap.put("key", item.getDictKey());
                webMap.put("label", item.getDictValue());
                webMap.put("id", item.getDictItemId().toString());
                webMap.put("parentId", item.getDictItemId().toString());
                dictItems.add(webMap);
                itemsMap.put(item.getDictKey(), item.getDictValue());
            }
            redisHandle.set(Constants.REDIS_PREFIX_DIC + code, itemsMap);
            redisHandle.set(Constants.REDIS_PREFIX_WEB_DIC + code, dictItems);
            dictMaps.put(code, dictItems);
        }
        redisHandle.set(Constants.REDIS_PREFIX_WEB_DIC, dictMaps);
        Date d = new Date();
        //更新本号
        String version = DateUtils.formatDate(d, "yyyyMMddHHmmss");
        redisHandle.hset(RedisConstant.DIC_CACHE_VERSION_TABLE, RedisConstant.DIC_DICT_VERSION, version);
        log.info("更新数据字典版本为:{}", version);
        log.info("添加基础数据字典 结束 共计{}秒", (System.currentTimeMillis() - start) / 1000.0);
    }
}

 sy_dict与sp_dict——items表:

CREATE TABLE `sy_dict` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主码',
  `dict_code` varchar(32) NOT NULL DEFAULT '' COMMENT '标识',
  `company_id` int(11) DEFAULT '0' COMMENT '归属公司(0公用)',
  `is_disabled` tinyint(4) DEFAULT '1' COMMENT '是否可删除编辑 0 不可删除编辑,1可删除编辑',
  `description` varchar(100) DEFAULT '' COMMENT '字典描述',
  `created_date` datetime DEFAULT NULL COMMENT '创建时间',
  `created_by` int(11) DEFAULT NULL COMMENT '创建者',
  `updated_date` datetime DEFAULT NULL COMMENT '更新人',
  `updated_by` int(11) DEFAULT NULL COMMENT '更改人',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=213 DEFAULT CHARSET=utf8 COMMENT='数据字典表';


CREATE TABLE `sy_dict_items` (
  `dict_item_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主码',
  `dict_id` int(11) NOT NULL COMMENT '字典id',
  `dict_key` varchar(32) DEFAULT '' COMMENT '键',
  `dict_value` varchar(100) DEFAULT '' COMMENT '值',
  `priority` int(11) DEFAULT '0' COMMENT '优先级',
  `parent_id` int(11) DEFAULT NULL COMMENT '父子项目id',
  PRIMARY KEY (`dict_item_id`),
  KEY `fk_dictitem_dictid` (`dict_id`),
  CONSTRAINT `sy_dict_items_ibfk_1` FOREIGN KEY (`dict_id`) REFERENCES `sy_dict` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=1509 DEFAULT CHARSET=utf8 COMMENT='数据字典表';

 


posted @ 2018-09-06 11:27  huanghaunghui  阅读(936)  评论(0编辑  收藏  举报