数据字典的好处很多比如:
1、可以减少使用表,来专门记录类型。
2、类型使用key检索,或者报表统计分析,在一定程度上相比汉字来讲,效率好得多。
3、使用缓存的数据字典、也可以减少不少的io操作。
等等、、、、
首先,库表设计就智者见智了、不多说、爱怎么设计就怎么设计。
完整的数据字典设计 ,需要
1、生成select 自定义标签。
2、list页面,或者get页面, 一个key转 value的标签
使用自定义标签,搭配上缓存的数据字典是最方便、最完美的解决办法,
接下来,就直接贴代码了。
一、数据字典缓存配置:
1、数据字典缓存监听器(在web容器启动成功的时候、进行缓存)
web.xml
1 <listener>
2 <description>初始化数据字典</description>
3 <listener-class>com.hotent.core.web.listener.DictionaryCacheListener</listener-class>
4 </listener>
2、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 }
3、保存缓存数据字典的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>>();
}
CacheDict
4、为缓存注入数据 。 提示一点:在更新、或者添加数据字典的时候,记得重新调用缓存的方法、更新数据
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 }
5、 生成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 }
DictSelectTag
6、将数据字典通过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;
}
}
DictKey2Value
7、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>
tag.tld
看下页面使用效果:
<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,