引入场景: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
字段,效果如上,成功渲染!
写一个定时任务,定时刷新缓存,不然缓存和字典表的数据不同步!