spring Cache + Redis 开发数据字典以及自定义标签

一、数据库表结构

1、  分类表:dict_type

       《spring Cache + Redis 开发数据字典以及自定义标签》

2、  子项表:dict_entry

 《spring Cache + Redis 开发数据字典以及自定义标签》

二、页面维护功能示意图:

1、  分类管理 点击子项管理进入子项管理页面

    《spring Cache + Redis 开发数据字典以及自定义标签》

2、子项管理

    《spring Cache + Redis 开发数据字典以及自定义标签》

三、数据字典添加到缓存:

数据字典为了读取效率高效,减少与数据库的交互,通常会把数据字典所有数据添加到缓存当中,如果是一台服务器部署,只需放到本机中就可以,如果需要部署到多台服务器分布式部署的话需要把数据字典同步到Redis服务器中。

1、  springboot 在dictTypeService中把数据字典放到本机缓存中

《spring Cache + Redis 开发数据字典以及自定义标签》

对数据字典进行增删改查时需要调用refreshDictCache()方法来刷新缓存,保证缓存中数据为最新数据

2、  如果使用springboot + Redis做缓存的使用的方法,在dictTypeService中把数据字典放到Redis服务器中

《spring Cache + Redis 开发数据字典以及自定义标签》

@Cacheable(value=”dictEntry”, key=”T(String).valueOf(‘dictEntryMap’)”)

使用此注解调用此方法时,系统会先从Redis服务器获取数据字典,如果取不到数据,系统会再去数据库读取。

《spring Cache + Redis 开发数据字典以及自定义标签》

@CacheEvict(value=”dictEntry”, key=”T(String).valueOf(‘dictTypeNameMap’)”)

方法使用此注解,对数据字典进行增删改查时,系统会自动同步到Redis服务器,保证数据库数据与redis数据保持一致。

三、把数据字典做成自定义标签

1、  创建辅助类(自定义标签调用)

  1 package com.hydwltech.iems.epum.common.utils;
  2 
  3 import java.util.ArrayList;
  4 import java.util.List;
  5 
  6 import org.apache.commons.lang.StringUtils;
  7 
  8 import com.hydwltech.iems.epum.entity.dict.DictEntryOV;
  9 import com.hydwltech.iems.epum.service.dict.DictTypeService;
 10 
 11 /**
 12  * 数据字典工具类
 13  **/
 14 public class DictUtil {
 15     private static DictTypeService getDictTypeService() {
 16         return SpringWebContextUtil.getApplicationContext().getBean(DictTypeService.class);
 17     }
 18 
 19     /**
 20      * 根据类型编码获取子项列表
 21      * 
 22      * @param dictTypeCode 类型编码
 23      * @return List<{@link DictEntryOV}}> 子项数据对象
 24      */
 25     @SuppressWarnings("unchecked")
 26     public static List<DictEntryOV> getDictEntryList(String dictTypeCode) {
 27         return (List<DictEntryOV>) getDictTypeService().getDictEntryMap().get(dictTypeCode);
 28     }
 29 
 30     /**
 31      * 根据类型编码和子项编码获得子项名称
 32      * 
 33      * @param dictTypeCode  类型编码
 34      * @param dictEntryCode 子项编码
 35      * @return String 子项名称
 36      */
 37     public static String getDictEntryName(String dictTypeCode, String dictEntryCode) {
 38         if (StringUtils.isBlank(dictTypeCode)) {
 39             return null;
 40         }
 41         if (StringUtils.isBlank(dictEntryCode)) {
 42             return null;
 43         }
 44         List<DictEntryOV> ovlist = (List<DictEntryOV>) getDictTypeService().getDictEntryMap().get(dictTypeCode);
 45         String entryCode = null;
 46         if (isInteger(dictEntryCode)) {
 47             List<String> nameMapKeys = new ArrayList<String>();
 48             for (DictEntryOV dictOv : ovlist) {
 49                 String[] names = dictOv.getDictEntryCode().split(",");
 50                 boolean namesIsInt = true;
 51                 for (int i = 0; i < names.length; i++) {
 52                     if (!isInteger(names[i])) {
 53                         namesIsInt = false;
 54                         break;
 55                     }
 56                 }
 57                 if (namesIsInt) {
 58                     nameMapKeys.add(dictOv.getDictEntryCode());
 59                 }
 60             }
 61 
 62             for (String parm : nameMapKeys) {
 63                 if (parm.split(",").length == 1) {
 64                     int parm1 = Integer.parseInt(parm.split(",")[0]);
 65                     if (Integer.parseInt(dictEntryCode) == parm1) {
 66                         entryCode = parm;
 67                     }
 68                 } else if (parm.split(",").length == 2) {
 69                     int parm1 = Integer.parseInt(parm.split(",")[0]);
 70                     int parm2 = Integer.parseInt(parm.split(",")[1]);
 71                     if (Integer.parseInt(dictEntryCode) >= parm1 && Integer.parseInt(dictEntryCode) <= parm2) {
 72                         entryCode = parm;
 73                     }
 74                 }
 75             }
 76         } else {
 77             entryCode = dictEntryCode;
 78         }
 79 
 80         String entryName = null;
 81         if (StringUtils.isNotBlank(entryCode)) {
 82             for (DictEntryOV dictEntryOV : ovlist) {
 83                 if (entryCode.equals(dictEntryOV.getDictEntryCode())) {
 84                     entryName = dictEntryOV.getDictEntryName();
 85                 }
 86             }
 87         }
 88         
 89         return entryName;
 90     }
 91 
 92     /**
 93      * 根据类型编码和子项编码获得子项对象
 94      * 
 95      * @param dictTypeCode  类型编码
 96      * @param dictEntryCode 子项编码
 97      * @return DictEntryOV 子项名称
 98      */
 99     public static DictEntryOV getDictEntry(String dictTypeCode, String dictEntryCode) {
100         if (StringUtils.isBlank(dictTypeCode)) {
101             return null;
102         }
103         if (StringUtils.isBlank(dictEntryCode)) {
104             return null;
105         }
106         List<DictEntryOV> ovlist = (List<DictEntryOV>) getDictTypeService().getDictEntryMap().get(dictTypeCode);
107         DictEntryOV entryOv = null;
108         for (DictEntryOV dictEntryOV : ovlist) {
109             if (dictEntryCode.equals(dictEntryOV.getDictEntryCode())) {
110                 entryOv = dictEntryOV;
111             }
112         }
113         return entryOv;
114     }
115 
116     /**
117      * 根据类型编码和子项编码获得子项名称
118      * 
119      * @param dictTypeCodeAndEntryCode 类型编码和子项编码合成字符串两个变量已逗号隔开
120      * @return String 子项名称
121      */
122     public static String getDictEntryNameByCodes(String dictTypeCodeAndEntryCode) {
123         if (StringUtils.isBlank(dictTypeCodeAndEntryCode)) {
124             return null;
125         }
126         String[] params = dictTypeCodeAndEntryCode.split(",");
127         String dictTypeCode = params[0];
128         String dictEntryCode = params[1];
129         List<DictEntryOV> ovlist = (List<DictEntryOV>) getDictTypeService().getDictEntryMap().get(dictTypeCode);
130         String entryName = null;
131         for (DictEntryOV dictEntryOV : ovlist) {
132             if (dictEntryCode.equals(dictEntryOV.getDictEntryCode())) {
133                 entryName = dictEntryOV.getDictEntryName();
134             }
135         }
136         return entryName;
137     }
138 
139     /**
140      * 根据类型编码获得类型名称
141      * 
142      * @param dictTypeCode 类型编码
143      * @return String 子项名称
144      */
145     public static String getDictTypeName(String dictTypeCode) {
146         if (StringUtils.isBlank(dictTypeCode)) {
147             return null;
148         }
149         String type = (String) getDictTypeService().getDictTypeNameMap().get(dictTypeCode);
150         return type;
151 
152     }
153 
154     /**
155      * 根据类型编码和子项名称获得子项类型编码
156      * 
157      * @param dictTypeCode  类型编码
158      * @param dictEntryName 子项名称
159      * @return String 子项编码
160      */
161     public static String getDictEntryCodeByEntryName(String dictTypeCode, String dictEntryName) {
162         if (StringUtils.isBlank(dictTypeCode)) {
163             return null;
164         }
165         if (StringUtils.isBlank(dictEntryName)) {
166             return null;
167         }
168         List<DictEntryOV> ovlist = (List<DictEntryOV>) getDictTypeService().getDictEntryMap().get(dictTypeCode);
169         String entryCode = null;
170         for (DictEntryOV ov : ovlist) {
171             if (dictEntryName.equals(ov.getDictEntryName())) {
172                 entryCode = ov.getDictEntryCode();
173             }
174         }
175         return entryCode;
176     }
177 
178     /** 验证是否是整数 */
179     private static boolean isInteger(String param) {
180         try {
181             Integer.valueOf(param);
182             return true;
183         } catch (Exception e) {
184             // TODO: handle exception
185         }
186         return false;
187     }
188 }

2、  自定义JSTL标签类

   (1)需要定义几个标签,就写几个独立的标签类

《spring Cache + Redis 开发数据字典以及自定义标签》

  (2)定义标签类,在页面输出下拉菜单数据

 1 package com.hydwltech.iems.epum.common.utils.tag;
 2 
 3 import java.util.List;
 4 
 5 import javax.servlet.jsp.JspException;
 6 import javax.servlet.jsp.tagext.TagSupport;
 7 
 8 import com.hydwltech.iems.epum.common.utils.DictUtil;
 9 import com.hydwltech.iems.epum.entity.dict.DictEntryOV;
10 
11 public class ValueDictEntryListUtil extends TagSupport{
12 
13     /**
14      * 
15      */
16     private static final long serialVersionUID = 1L;
17     
18     private String var;
19 
20     @Override
21     public int doStartTag() throws JspException {
22         try {
23             StringBuffer strBuffer = new StringBuffer();
24             List<DictEntryOV> ovList = DictUtil.getDictEntryList(var);
25             for (int i = 0; i < ovList.size(); i++) {
26                 strBuffer.append("<li>");
27                 strBuffer.append("<a href=\"###\" value="+ovList.get(i).getDictEntryCode()+">" + ovList.get(i).getDictEntryName() + "</a>");
28                 strBuffer.append("</li>");
29             }
30             pageContext.getOut().print(strBuffer.toString());
31         } catch (Exception e) {
32             // TODO: handle exception
33         }
34         return EVAL_BODY_INCLUDE;
35     }
36     
37 
38     public String getVar() {
39         return var;
40     }
41 
42     public void setVar(String var) {
43         this.var = var;
44     }
45 }

(3)、创建tld文件

      在WEB-INF下创建tld文件 dict.tld

 1 <?xml version="1.0" encoding="UTF-8"?>  
 2 <!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"    
 3     "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
 4 <taglib>
 5     <tlib-version>1.0</tlib-version><!-- 标签库版本 -->
 6     <jsp-version>1.2</jsp-version>  <!-- 标签库要求的JSP规范版本 -->
 7     <short-name>dict</short-name>   <!-- JSP页面编写工具可以用来创建助记名的可选名字 -->
 8     <!-- 
 9          为自定义标签库设置一个uri,uri以/开头,/后面的内容随便写,如这里的/gacl ,
10          在Jsp页面中引用标签库时,需要通过uri找到标签库
11          在Jsp页面中就要这样引入标签库:
12          <%@taglib uri="/security/encrypt" prefix="encrypt"%>
13      -->
14     <!-- <uri>/security/encrypt</uri> -->
15     <tag>
16         <name>entry</name>
17         <tag-class>com.hydwltech.iems.epum.common.utils.tag.ValueDictEntryNameUtil</tag-class>
18         <body-content>JSP</body-content>
19         <attribute>
20             <name>typeCode</name>
21             <rtexprvalue>true</rtexprvalue>
22         </attribute>
23         <attribute>
24             <name>entryCode</name>
25             <rtexprvalue>true</rtexprvalue>
26         </attribute>
27     </tag>
28     
29     <tag>
30         <name>type</name>
31         <tag-class>com.hydwltech.iems.epum.common.utils.tag.ValueDictTypeNameUtil</tag-class>
32         <body-content>JSP</body-content>
33         <attribute>
34             <name>var</name>
35             <rtexprvalue>true</rtexprvalue>
36         </attribute>
37     </tag>
38     
39     <tag>
40         <name>select</name>
41         <tag-class>com.hydwltech.iems.epum.common.utils.tag.ValueDictEntryListUtil</tag-class>
42         <body-content>JSP</body-content>
43         <attribute>
44             <name>var</name>
45             <rtexprvalue>true</rtexprvalue>
46         </attribute>
47     </tag>
48 </taglib>  

《spring Cache + Redis 开发数据字典以及自定义标签》

(4)、JSP页面调用标签

      A、导入自定义标签

       <%@ taglib prefix=“dict” uri=“/WEB-INF/tag/dict.tld”%>

      《spring Cache + Redis 开发数据字典以及自定义标签》

    B、下拉菜单调用此标签

       <dict:select var=”equipEablePatrol”/>

《spring Cache + Redis 开发数据字典以及自定义标签》

 

效果如下图:

《spring Cache + Redis 开发数据字典以及自定义标签》

除了下拉菜单标签,还可以根据自己的需求开发其他自定义标签。

四、相关技术链接

      关于自定义标签转自:https://blog.csdn.net/bilahepan/article/details/54801540

      关于Springboot  + cacheable + Redis转自:https://blog.csdn.net/moshowgame/article/details/80792774

点赞