关于使用Spring的缓存,将携带父id及所有子类全部数据获取,存入缓存,提高性能
本项目数据库建立时采用父子类id,以父类id,指向子类的id,将相关数据,转为树形结构传给前端,把相应数据转化为前端后,发现出现递归查询数据库,每次查询都会访问一次,导致数据加载缓慢,后来,便引用Spring的自带缓存,将数据先查询,放入缓存,后每次查询只需从缓存中获取,提高效率!!!
dao.xml层:
!-- 根据id获取字典列表--> <select id="findTreeList" resultType="com.longfor.longcity.modules.sys.dto.response.DictDto"> SELECT a.TYPE AS dictType,a.id,a.label AS dictName,a.show_end AS showEn,a,status,a.election FROM sys_dict a WHERE a.parent_id = #{id} AND del_flag = #{DEL_FLAG_NORMAL} </select> <!-- 根据id获取节点对象--> <select id="findById" resultType="com.longfor.longcity.modules.sys.dto.response.DictDto"> SELECT a.TYPE as dictType,a.id,a.label AS dictName,a.show_end AS showEnd,a.status,a.election FROM sys_dict a WHERE a.id = #{id} </select>
dao层:
/** * 根据类型返回此类型的字典树 * @param dict * @return 字典树 */ List<DictDto> findTreeList(Dict dict); /** * 根据类型返回此类型的节点对象 * @param id * @return 节点对象 */ DictDto findById(@Param("id")Long id);
开启Spring的Cache缓存:
/** * Cache工具类 */
public class CacheUtils { // ================================================================ // Constants // ================================================================ /** * 默认cache的key. */ public static final String SYS_CACHE = "sysCache"; // ================================================================ // Fields // ================================================================ /** * cache管理器,从spring获得. */ private static CacheManager cacheManager = SpringContextHolder.getBean(CacheManager.class); /** * 根据cache类型决定是否序列化,默认ehcache不序列化 */ private static boolean SERIALIZE_ABLE = false; // ================================================================ // Constructors // ================================================================ // ================================================================ // Methods from/for super Interfaces or SuperClass // ================================================================ // ================================================================ // Public or Protected Methods // ================================================================ /** * 获取SYS_CACHE缓存 * * @param key 键 * @return 值 */ public static Object get(String key) { return get(SYS_CACHE, key); } /** * 写入SYS_CACHE缓存 * * @param key 键 * @param value 值 */ public static void put(String key, Object value) { put(SYS_CACHE, key, value); } /** * 从SYS_CACHE缓存中移除 * * @param key 键 */ public static void remove(String key) { remove(SYS_CACHE, key); } /** * 获取缓存 * * @param cacheName 缓存KEY * @param key 键 * @return 值 */ public static Object get(String cacheName, String key) { Cache.ValueWrapper element = getCache(cacheName).get(key); // return element == null ? null : element.get(); if (element != null) { Object value = element.get(); if (value != null && SERIALIZE_ABLE) { return SerializeUtils.deserializeFromString(value.toString()); } else { return value; } } return null; } /** * 写入缓存 * * @param cacheName 缓存KEY * @param key 键 * @param value 值 */ public static void put(String cacheName, String key, Object value) { if (SERIALIZE_ABLE && value != null) { getCache(cacheName).put(key, SerializeUtils.serializeToString((Serializable) value)); } else { getCache(cacheName).put(key, value); } } /** * 从缓存中移除 * * @param cacheName 缓存KEY * @param key 键 */ public static void remove(String cacheName, String key) { // 从缓存中移除key对应的缓存 getCache(cacheName).evict(key); } /** * 从缓存中移除 * * @param cacheName 缓存KEY */ public static void removeAll(String cacheName) { // 从缓存中移除key对应的缓存 getCache(cacheName).clear(); } // ================================================================ // Getter & Setter // ================================================================ /** * 获取cache的管理者,目前是ehcache or redis * * @return 缓存管理器 */ public static CacheManager getCacheManager() { return cacheManager; } // ================================================================ // Private Methods // ================================================================ /** * 获得一个Cache,没有则创建一个。 * * @param cacheName 缓存KEY * @return 缓存 */ private static Cache getCache(String cacheName) { // 防止cache不为空,不设置序列化 if (cacheManager instanceof RedisCacheManager) { SERIALIZE_ABLE = true; } Cache cache = cacheManager.getCache(cacheName); if (cache == null) { if (cacheManager instanceof EhCacheCacheManager) { EhCacheCacheManager manager = (EhCacheCacheManager) cacheManager; net.sf.ehcache.CacheManager cm = manager.getCacheManager(); cm.addCache(cacheName); cm.getCache(cacheName).getCacheConfiguration().setEternal(false); SERIALIZE_ABLE = false; } else if (cacheManager instanceof RedisCacheManager) { RedisCacheManager manager = (RedisCacheManager) cacheManager; manager.setCacheNames(Lists.newArrayList(cacheName)); SERIALIZE_ABLE = true; } cache = cacheManager.getCache(cacheName); } return cache; } // ================================================================ // Inner or Anonymous Class // ================================================================ // ================================================================ // Test Methods // ================================================================ }
写了一个DictUtil:
/** * 字典工具类 */ public class DictUtils { /** * 根据id获取字典列表 * @param id 字典 * @return 树形字典列表 */ public static DictDto getDictTree(Long id) { Map<Long, DictDto> dictMap = (Map<Long, DictDto>) CacheUtils.get(CACHE_DICT_MAP); if (dictMap == null || dictMap.get(id)==null) { dictMap = Maps.newHashMap(); dictMap.put(id,treeDataList(id)); CacheUtils.put(CACHE_DICT_MAP, (Serializable) dictMap); } DictDto dictDto = dictMap.get(id); return dictDto; } // ================================================================ // Getter & Setter // ================================================================ // ================================================================ // Private Methods /** * 根据id构建字典树 */ private static DictDto treeDataList(@RequestParam(required = false) Long id) { Dict dict = new Dict(); dict.setId(id); DictDto dictDto = dictDao.findById(id); List<DictDto> list = dictDao.findTreeList(dict); for (DictDto e : list) { if (e.getStatus() == 0) { // 弃用不加入 } dictDto.getNodes().add(treeDataList(e.getId())); } return dictDto; }
service层:
/** * 字典树 */ public DictDto findTreeList( Dict dict){return DictUtils.getDictTree(dict.getId());} /** * 根据类型返回此类型的节点对象 * @param id * @return 节点对象 */ public DictDto findById(Long id){return dao.findById(id);}
Controller层:
/** * 字典Controller */ @RestController @RequestMapping(value = "/services/v1/dict") public class DictController extends BaseController { @Autowired private DictService dictService;
@RequestMapping(value = "treeData", method = {RequestMethod.GET, RequestMethod.POST}) /*public Wrapper treeData(@RequestParam(required = false) String type) { List<Map<String, Object>> mapList = Lists.newArrayList(); Dict dict = new Dict(); dict.setType(type); List<Dict> list = dictService.findList(dict); for (Dict e : list) { Map<String, Object> map = Maps.newHashMap(); map.put("id", e.getId()); map.put("pId", e.getParentId()); map.put("name", StringUtils.replace(e.getLabel(), " ", "")); mapList.add(map); } return WrapMapper.ok().result(mapList); }*/ public Wrapper treeData(@RequestParam(required = false) Long id) { Dict dict = new Dict(); dict.setId(id); dictService.findTreeList(dict); return WrapMapper.ok().result(dictService.findTreeList(dict)); }}