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

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

一,要实现的效果描述

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

二,设计步骤

  • 项目启动的同时要读取字典表,并把读取到字典表的内容存储到内存中
  • 前端页面检索所有的 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字段,效果如上,成功渲染!
    写一个定时任务,定时刷新缓存,不然缓存和字典表的数据不同步!

    作者:樊同学