數據字典的好處不少好比:java
一、能夠減小使用表,來專門記錄類型。node
二、類型使用key檢索,或者報表統計分析,在必定程度上相比漢字來說,效率好得多。web
三、使用緩存的數據字典、也能夠減小很多的io操做。spring
等等、、、、數據庫
首先,庫表設計就智者見智了、很少說、愛怎麼設計就怎麼設計。apache
完整的數據字典設計 ,須要 緩存
一、生成select 自定義標籤。安全
二、list頁面,或者get頁面, 一個key轉 value的標籤app
使用自定義標籤,搭配上緩存的數據字典是最方便、最完美的解決辦法,jsp
接下來,就直接貼代碼了。
1、數據字典緩存配置:
一、數據字典緩存監聽器(在web容器啓動成功的時候、進行緩存)
web.xml
1 <listener> 2 <description>初始化數據字典</description> 3 <listener-class>com.hotent.core.web.listener.DictionaryCacheListener</listener-class> 4 </listener>
二、DictionaryCacheListener
1 package com.*****.core.web.listener; 2 import javax.servlet.ServletContextEvent; 4 import org.springframework.web.context.WebApplicationContext; 5 import org.springframework.web.context.support.WebApplicationContextUtils; 7 import com.*****.platform.service.system.DictionaryService; 8 9 public class DictionaryCacheListener implements javax.servlet.ServletContextListener { 10 11 @Override 12 public void contextDestroyed(ServletContextEvent arg0) { 14 }
16 @Override 17 public void contextInitialized(ServletContextEvent arg0) { 18 19 System.out.println("++++++++++++++++++ 數據字典已緩存 +++++++++++++++++++++"); 20 WebApplicationContext webApplicationContext = WebApplicationContextUtils.getWebApplicationContext(arg0.getServletContext()); 21 DictionaryService dc = (DictionaryService) webApplicationContext.getBean("dictionaryService"); 22 dc.getCacheDic(); // 調用數據字典Manager的一個方法來緩存 24 } 25 26 }
三、保存緩存數據字典的BO //(也能夠放在平臺緩存的BO裏面,那共用的緩存設計要考慮線程安全了,簡單起見這麼搞。)
import java.util.HashMap; import java.util.List; import java.util.Map; import com.hotent.platform.model.system.Dictionary; import com.hotent.platform.model.system.GlobalType; /** * 緩存數據字典 * @author miao * */ public class CacheDict { /** * 全部的數據字典類型 */ public static Map<String,GlobalType> allTypes = new HashMap<String, GlobalType>(); /** * 全部類型,對應的數據字典項 */ public static Map<String, List<Dictionary>> dictList = new HashMap<String,List<Dictionary>>(); /** * 類型與字典項 由List 轉成Map(key,value) */ public static Map<String, Map<Long,String>> dictMap = new HashMap<String,Map<Long,String>>(); }
四、爲緩存注入數據 。 提示一點:在更新、或者添加數據字典的時候,記得從新調用緩存的方法、更新數據
1 public void getCacheDic() { 2 //GlobalType 裏面存儲全部的各類類型:附件類型,數據字典類型,流程類型等等 3 List<GlobalType> globalTypes = globalTypeDao.getByCatKey(GlobalType.CAT_DIC); //eg:性別‘學歷等 4 CacheDict.allTypes.clear(); 5 CacheDict.dictList.clear(); 6 CacheDict.dictMap.clear(); 7 8 for(GlobalType DicType : globalTypes){ 9 CacheDict.allTypes.put(DicType.getNodeKey(),DicType); 10 11 List<Dictionary> dictList = this.getByNodeKey(DicType.getNodeKey());//經過key 查找 全部數據項 12 13 CacheDict.dictList.put(DicType.getNodeKey(),dictList ); 14 15 //字典項轉成key - value的形式 16 Map<Long, String> map = new HashMap<Long, String>(); 17 for(Dictionary dic : dictList){ 18 map.put(dic.getDicId(),dic.getItemName()); // key / name 19 } 20 CacheDict.dictMap.put(DicType.getNodeKey(),map); 21 } 22 System.out.println("+++++++++++++++++++++++++ "+globalTypes.size()+" +++++++++++++++++++++" ); 23 }
五、 生成select 框自定義標籤
1 import java.io.IOException; 2 import java.util.List; 3 4 import javax.servlet.jsp.JspTagException; 5 import javax.servlet.jsp.JspWriter; 6 import javax.servlet.jsp.tagext.TagSupport; 7 8 import org.apache.commons.lang.StringUtils; 9 10 import com.hotent.core.cache.impl.CacheDict; 11 import com.hotent.platform.model.system.Dictionary; 12 13 14 /** 15 * 16 * 選擇下拉框 17 * 18 * @author: miao 19 * @date: 日期:2013-9-25 23:14:26 20 * @version 1.0 21 */ 22 public class DictSelectTag extends TagSupport { 23 private String id; //EAMPLE:<select name="selectName" id = "" /> 24 private String name; 25 private String title; 26 private String value =""; //默認值 便是回顯 ID 27 private String nodeKey; //數據字典節點 28 private String divClass; //DIV樣式 29 private String labelClass; //Label樣式 30 private boolean hasLabel = false; //是否顯示label 31 private String clazz; 32 private String style; 33 private boolean required =false; // 若是必須選擇、則添加required = true 34 35 public int doStartTag() throws JspTagException { 36 return EVAL_PAGE; 37 } 38 39 public int doEndTag() throws JspTagException { 40 try { 41 JspWriter out = this.pageContext.getOut(); 42 out.print(end().toString()); 43 } catch (IOException e) { 44 e.printStackTrace(); 45 } 46 return EVAL_PAGE; 47 } 48 49 50 public StringBuffer end() { 51 StringBuffer sb = new StringBuffer(); 52 try{ 53 if (StringUtils.isBlank(divClass)) { 54 divClass = ""; //默認form樣式 55 } 56 if (StringUtils.isBlank(labelClass)){ 57 labelClass = ""; //默認label樣式 58 } 59 /* ServletContext servletContext = pageContext.getServletContext(); 60 ApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(servletContext); 61 ApplicationContext context = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext); 62 DictionaryService dictioninaryService = (DictionaryService)context.getBean("dictionaryService"); 63 List<Dictionary> dictionary = dictioninaryService.getByNodeKey(this.getNodeKey()); 64 從applicationContext裏面獲取 service方法、獲取數據字典、、 更新爲從緩存對象中獲取數據字典。 update time 2013-9-28 15:25:48 65 */ 66 List<Dictionary> dictionary = CacheDict.dictList.get(this.getNodeKey()); 67 if (hasLabel) { 68 sb.append("<div class=\""+divClass+"\">"); 69 sb.append("<label class=\""+labelClass+"\" >"); 70 } 71 if (dictionary == null) { 72 sb.append("<span color=\"red\"> 此nodekey 未查找到數據字典</span>"); 73 }else { 74 if (hasLabel) { 75 if (StringUtils.isBlank(this.title)) { 76 this.title ="選項"; 77 } 78 sb.append(this.title+":"); 79 sb.append("</label>"); 80 } 81 if(required) 82 sb.append("<select name=\""+name+"\" validate =\"{required:true}\" class=\""+this.getClazz()+"\" style=\""+this.getStyle()+"\"" ); 83 else 84 sb.append("<select name=\""+name+"\" class=\""+this.getClazz()+"\" style=\""+this.getStyle()+"\"" ); 85 if (!StringUtils.isBlank(this.id)) { 86 sb.append(" id=\""+id+"\""); 87 } 88 sb.append(">"); 89 // if(this.getValue().equals(""));{ 90 sb.append("<option value = \"\">請選擇</option>"); // 91 for (Dictionary dic : dictionary) { 92 /* String v = this.getValue(); 93 Long i = dic.getDicId();*/ 94 if (dic.getDicId().toString().equals(this.getValue()) ) { 95 sb.append(" <option value=\""+dic.getDicId()+"\" selected=\"selected\">"); 96 }else { 97 sb.append(" <option value=\""+dic.getDicId()+"\">"); 98 } 99 sb.append(dic.getItemName()); 100 sb.append(" </option>"); 101 } 102 103 sb.append("</select>"); 104 if (hasLabel) { 105 sb.append("</div>"); 106 } 107 } 108 }catch (Exception e) { 109 e.printStackTrace(); 110 return sb.append("<span color=\"red\"> <h1>異常</h1>此nodekey: "+ this.nodeKey+" 查找數據庫數據字典異常<br/>"+e.getMessage()+"</span>"); 111 } 112 return sb; 113 } 114 115 public String getValue() { 116 return value; 117 } 118 119 public void setValue(String value) { 120 this.value = value; 121 } 122 123 public String getId() { 124 return id; 125 } 126 127 public void setId(String id) { 128 this.id = id; 129 } 130 131 132 public String getDivClass() { 133 return divClass; 134 } 135 136 public void setDivClass(String divClass) { 137 this.divClass = divClass; 138 } 139 140 public String getLabelClass() { 141 return labelClass; 142 } 143 144 public void setLabelClass(String labelClass) { 145 this.labelClass = labelClass; 146 } 147 148 public String getTitle() { 149 return title; 150 } 151 152 public void setTitle(String title) { 153 this.title = title; 154 } 155 156 public String getNodeKey() { 157 return nodeKey; 158 } 159 160 public void setNodeKey(String nodeKey) { 161 this.nodeKey = nodeKey; 162 } 163 164 public boolean isHasLabel() { 165 return hasLabel; 166 } 167 168 public void setHasLabel(boolean hasLabel) { 169 this.hasLabel = hasLabel; 170 } 171 172 public String getName() { 173 return name; 174 } 175 176 public String getClazz() { 177 return clazz; 178 } 179 180 public boolean isRequired() { 181 return required; 182 } 183 184 public void setRequired(boolean required) { 185 this.required = required; 186 } 187 188 public void setClazz(String clazz) { 189 this.clazz = clazz; 190 } 191 192 public void setName(String name) { 193 this.name = name; 194 } 195 196 197 public String getStyle() { 198 return style; 199 } 200 201 public void setStyle(String style) { 202 this.style = style; 203 } 204 205 206 207 208 }
六、將數據字典經過key 轉換成value
import java.io.IOException; import java.util.Map; import javax.servlet.jsp.JspTagException; import javax.servlet.jsp.JspWriter; import javax.servlet.jsp.tagext.TagSupport; import com.hotent.core.cache.impl.CacheDict; public class DictKey2Value extends TagSupport { private Long key; private String nodeKey; public int doStartTag() throws JspTagException { return EVAL_PAGE; } public int doEndTag() throws JspTagException { try { JspWriter out = this.pageContext.getOut(); out.print(dictName().toString()); } catch (IOException e) { e.printStackTrace(); } return EVAL_PAGE; } public StringBuffer dictName() { StringBuffer sb = new StringBuffer(); Map map = CacheDict.dictMap.get(this.getNodeKey()); if(map == null) sb.append("未發現NodeKey"); else{ if(map.get(key)!=null) sb.append( map.get(key)); } return sb; } public String getNodeKey() { return nodeKey; } public void setNodeKey(String nodeKey) { this.nodeKey = nodeKey; } public Long getKey() { return key; } public void setKey(Long key) { this.key = key; } }
七、tag標籤配置
1 <!-- 數據字典標籤 --> 2 <tag> 3 <name>dict</name> 4 <description>數據字典</description> 5 <tag-class>com.hotent.core.web.tag.DictSelectTag</tag-class> 6 <body-content>JSP</body-content> 7 <display-name>數據字典選擇控件</display-name> 8 <attribute> 9 <name>id</name> 10 <required>false</required> 11 <rtexprvalue>true</rtexprvalue> 12 </attribute> 13 <attribute> 14 <name>required</name> 15 <required>false</required> 16 <rtexprvalue>true</rtexprvalue> 17 </attribute> 18 <attribute> 19 <name>name</name> 20 <required>true</required> 21 <rtexprvalue>true</rtexprvalue> 22 </attribute> 23 <attribute> 24 <name>title</name> 25 <required>false</required> 26 <rtexprvalue>true</rtexprvalue> 27 </attribute> 28 <attribute> 29 <name>value</name> 30 <required>true</required> 31 <rtexprvalue>true</rtexprvalue> 32 </attribute> 33 <attribute> 34 <name>nodeKey</name> 35 <required>true</required> 36 <rtexprvalue>true</rtexprvalue> 37 <description>數據字典的節點key</description> 38 </attribute> 39 <attribute> 40 <name>divClass</name> 41 <required>false</required> 42 <rtexprvalue>true</rtexprvalue> 43 </attribute> 44 <attribute> 45 <name>labelClass</name> 46 <required>false</required> 47 <rtexprvalue>true</rtexprvalue> 48 </attribute> 49 <attribute> 50 <name>hasLabel</name> 51 <required>false</required> 52 <rtexprvalue>true</rtexprvalue> 53 </attribute> 54 <attribute> 55 <name>clazz</name> 56 <required>false</required> 57 <rtexprvalue>true</rtexprvalue> 58 </attribute> 59 <attribute> 60 <name>style</name> 61 <required>false</required> 62 <rtexprvalue>true</rtexprvalue> 63 </attribute> 64 </tag> 65 <tag> 66 <name>dicK2V</name> 67 <description>數據字典</description> 68 <tag-class>com.hotent.core.web.tag.DictK2V</tag-class> 69 <body-content>JSP</body-content> 70 <display-name>數據轉換</display-name> 71 <attribute> 72 <name>key</name> 73 <required>true</required> 74 <rtexprvalue>true</rtexprvalue> 75 </attribute> 76 <attribute> 77 <name>nodeKey</name> 78 <required>true</required> 79 <rtexprvalue>true</rtexprvalue> 80 </attribute> 81 </tag>
看下頁面使用效果:
<f:dict name="sex" nodeKey="sex" required="true" value="${user.sex}" clazz="class樣式" style="width:150px !important" ></f:dict>
//生成標準的select標籤、能夠添加本身的樣式等、
<f:dicK2V nodeKey="sex" key="${user.sex}"></f:dicK2V>
over,