一、數據庫表結構
1、 分類表:dict_type

2、 子項表:dict_entry

二、頁面維護功能示意圖:
1、 分類管理 點擊子項管理進入子項管理頁面

2、子項管理

三、數據字典添加到緩存:
數據字典為了讀取效率高效,減少與數據庫的交互,通常會把數據字典所有數據添加到緩存當中,如果是一台服務器部署,只需放到本機中就可以,如果需要部署到多台服務器分布式部署的話需要把數據字典同步到Redis服務器中。
1、 springboot 在dictTypeService中把數據字典放到本機緩存中

對數據字典進行增刪改查時需要調用refreshDictCache()方法來刷新緩存,保證緩存中數據為最新數據
2、 如果使用springboot + Redis做緩存的使用的方法,在dictTypeService中把數據字典放到Redis服務器中

@Cacheable(value="dictEntry", key="T(String).valueOf('dictEntryMap')")
使用此注解調用此方法時,系統會先從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)需要定義幾個標簽,就寫幾個獨立的標簽類

(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>

(4)、JSP頁面調用標簽
A、導入自定義標簽
<%@ taglib prefix="dict" uri="/WEB-INF/tag/dict.tld"%>

B、下拉菜單調用此標簽
<dict:select var="equipEablePatrol"/>

效果如下圖:

除了下拉菜單標簽,還可以根據自己的需求開發其他自定義標簽。
四、相關技術鏈接
關於自定義標簽轉自:https://blog.csdn.net/bilahepan/article/details/54801540
關於Springboot + cacheable + Redis轉自:https://blog.csdn.net/moshowgame/article/details/80792774
