Cache缓存字典的原理和实现

引入场景:select下拉框每次都要向后台发送请求,性能方面你们都懂,如何优化?
在数据库设计一个字典表,用于存放常用的下拉框选项内容,项目启动时查询字典表,并把查询结果存入内存,然后下拉框会到内存中找选项内容。

数据不同步问题:可以设置定时任务,刷新缓存即可。

一,要实现的效果描述

html页面的所有select标签,如果你加上一个指定好的自定义属性,那么会到缓存中读取下拉选项内容并自动渲染。
html内容
在这里插入图片描述
效果
在这里插入图片描述
字典表
value是下拉选项的值,text是下拉选项的显示内容,namecache属性对应的值,如果需要其他的,直接在表中添加即可,就是那么潇洒!
在这里插入图片描述

二,设计步骤

  1. 项目启动的同时要读取字典表,并把读取到字典表的内容存储到内存中
  2. 前端页面检索所有的select标签且带有cache属性的对象,js发送ajax到后台缓存器中读取,并渲染到select标签中。

三,开始表演

1,准备一个缓存管理器

package com.example.demo.Ctrl;
import org.springframework.stereotype.Component;
import org.thymeleaf.expression.Maps;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author FanJiangFeng
 * @version 1.0.0
 * @ClassName CacheManager.java
 * @Description TODO
 * @createTime 2020年06月04日 17:22:00
 */
@Component
public class CacheManager<T> {
    private Map<String, T> cache =new ConcurrentHashMap<>();

    public T get(String key){
        return  cache.get(key);
    }

    public void addOrUpdateCache(String key,T value) {
        cache.put(key, value);
    }

    // 依据 key 来删除缓存中的一条记录
    public void evictCache(String key) {
        if(cache.containsKey(key)) {
            cache.remove(key);
        }
    }

    // 清空缓存中的全部记录
    public void evictCache() {
        cache.clear();
    }
}

2,写查询SQL

@Component
@Mapper
public interface TestMapper {
    @Select(value = "select * from cache_dict")
    List<Map> getCacheDictData();
}

3,启动项目时初始化

项目启动时去数据库中取字典表数据并存入缓存管理器。

package com.example.demo.Ctrl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author FanJiangFeng
 * @version 1.0.0
 * @ClassName InitProject.java
 * @Description TODO
 * @createTime 2020年06月04日 17:31:00
 *
 * 该类需要继承ApplicationRunner接口并实现里面的run方法,并将该类通过@Component 注入到spring里
 * 随着项目启动而执行,用于初始化内容
 */
@Component
public class InitProject implements ApplicationRunner {
    @Autowired
    TestMapper testMapper;
    @Autowired
    CacheManager cacheManager;

    @Override
    public void run(ApplicationArguments args) throws Exception {
        System.out.println("#####################################");
        System.out.println("           初始化缓存管理器           ");
        System.out.println("#####################################");
        //刷新缓存字典,重新把缓存字典表的数据刷新到缓存管理器中
        List<Map> cacheDictData = testMapper.getCacheDictData();
        System.out.println("查到的缓存表数据:"+cacheDictData);
           cacheManager.addOrUpdateCache("cacheDict",cacheDictData);
           System.out.println("#########缓存字典表已刷新存入缓存管理器###########");
    }
}

4,准备ajax读取缓存的方法

参数是select标签的cache属性的值,通过值查询对应的下拉框选项内容。

 @RequestMapping("queryCache")
    @ResponseBody
    public List<Map> queryCache(String cacheName){
        List<Map> cacheDict = (List<Map>)cacheManager.get("cacheDict");
        List<Map> tempList=new ArrayList<>();
        for(Map map:cacheDict){
            if(cacheName.equals(map.get("name"))){
                tempList.add(map);
            }
        }
        return tempList;
    }

5,写一个公用的 js

js负责从html中扫描所有带有cache属性的select标签,并对其进行渲染

<script src="http://ajax.aspnetcdn.com/ajax/jquery/jquery-2.1.4.min.js"></script><script>
    $(function () {
               $("select").each(function () {
                   var _this=$(this);
                   var isHas=_this.attr('cache');
                   if(isHas!=undefined){
                       var temp='';
                       $.ajax({
                           url:"/test/queryCache",
                           data:{cacheName:isHas},
                           type:"post",
                           async:false,
                           success:function (data) {
                               for(var i=0;i<data.length;i++){
                                   temp+='<option value="'+data[i].value+'">'+data[i].text+'</option>';
                               }
                           }
                       });
                       _this.html(temp);
                   }
               });
    });
</script>

6,大结局

html页面测试,写一个select标签,加上指定属性cache,值为字典表的name字段,效果如上,成功渲染!
写一个定时任务,定时刷新缓存,不然缓存和字典表的数据不同步!

posted @ 2020-06-04 18:39  你樊不樊  阅读(567)  评论(0编辑  收藏  举报