需求:
在项目开发中,一些变量需要在多个地方使用,但这些变量的值是在某一范围内,且每一个值对应一个翻译的字面量。
?0?1 若是使用数据库存储,因为变量值是固定的,多余的数据库访问没有必要;
?0?1 若是直接硬编码到代码中,若是需要进行修改的时候,造成维护困难;
?0?1 若是以常量方式书写到类中并在使用时引用,你将发现你的常量类Constants里面内容庞杂,命名和使用都极其困难。
常见此类键值对如:
1.省代码表,省编码对应一个描述信息。
2.婚姻码表,例如1:单身, 2:未婚, 3:离异, 4:已婚, 5:恋爱中等。
3.教育码表,例如1:初中, 2:高中, 3:大专, 4:本科,
5:硕士, 6:博士等。
.........
这类键值对特点:在库中存储的是数字或字母编码,但在展示的时候使用的却是其文本内容
处理方式:
1. 将键值对内容书写到XML文件中。
2.系统启动时读取加载入内存。
3.使用时直接调用翻译 。
实现:
需要的xml文件(dics.xml),你可以自己定义:
<?xml version="1.0" encoding="UTF-8"?>
<dics>
<t id="marry"><!-- id是一个标识而已 -->
<r v="1">单身</r>
<r v="2">离异</r>
<r v="3>已婚</r>
<r v="4">恋爱中</r>
</t>
<t id="edu">
<r v="1">初中</r>
<r v="2">高中</r>
<r v="3">大专</r>
<r v="4">本科</r>
<r v="5">硕士</r>
<r v="6">博士</r>
</t>
</dics>Java代码,偶是利用Dom4j来处理xml文件,其中包含ClsLoader类,这个是一个工具类,我用来加载项目中的配置文件(包括WEB目录和类路径目录);
加载dics.xml文件,解析完成后,用HashMap缓存
public abstract class Dict {
/**缓存数据字典,如此使用:dics.get("marry");获取的是marry的字典数据,取某个文本:dics.get("marry").get("1")获取的就是“单身”文本,你可以自己定义一个方法,专门来获取*/
public static final Map<String,LinkedHashMap<String,String>> dics=new HashMap<String, LinkedHashMap<String, String>>();
/**
* 初始化数据字典,一般在过滤器或者servlet中的init方法中调用
*/
public static void init(){
SAXReader reader=new SAXReader();
try {
Document doc=reader.read(ClsLoader.getStream("dics.xml"));
Element root=doc.getRootElement();
for(Iterator<Element> ite=root.elementIterator("t");ite.hasNext();){
Element et=ite.next();
dics.put(et.attributeValue("id"),handT(et));//handT这个方法处理T下面的r元素
}
doc=null;root=null;
} catch (DocumentException e) {
throw new SysException("解析常量的XML文件出错!",e);
} catch (IOException e) {
throw new SysException("读取常量的XML文件出错!",e);
}
reader=null;
}
/**
* 处理R
* @param e 元素
* @return 元素下的r集合
*/
public static LinkedHashMap<String,String> handT(Element e){
LinkedHashMap<String,String> rs=new LinkedHashMap<String, String>();
for(Iterator<Element> er =e.elementIterator("r");er.hasNext();){
Element ers=er.next();
rs.put(ers.attributeValue("v"),ers.getText());
}
return rs;
}
/**
* web系统结束是销毁内存中的数据,一般在过滤器或者servlet 的destroy中调用
*/
public static void destroy(){
for(Map.Entry<String, LinkedHashMap<String,String>> entry:dics.entrySet()){
LinkedHashMap<String,String> m=entry.getValue();
m.clear();m=null;
}
dics.clear();
}
public static void main(String[] args)
{
long s=System.currentTimeMillis();
init();
System.out.println(dics.get("marry"));
System.out.println(dics.get("edu"));
System.out.println("耗时:"+(System.currentTimeMillis()-s));
destroy();
}
}那在你的JSP或者Freemarker中怎么使用呢?我用的是Freemarker,以Freemarker为例:
首先自定义 一个Freemaker的方法,Freemarker方法的自定义类如下:
public class DictDic implements TemplateMethodModel { @Override public Object exec(List args) throws TemplateModelException { int size=args.size(); String k=(String)args.get(0); if(size==1) return dics.get(k);//参数长度为1的时候获取的是指定类型的HashMap,例如 在ftl模板中调用${dict('marry')} if(size==2){ String v=(String)args.get(1);//参数长度为2的时候获取的是单个文本值,例如 在ftl模板中调用${dict('marry','2')}==离异 return dics.get(k).get(v); } return null; } }
将这个类注册到Freemarker的上下文中,这里给出Spring中的注册:
<bean id="dict" class="tqw.dic.DictDic"/><!--定义-->
<!-- Freemarker视图 配置 -->
<bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
<property name="freemarkerVariables">
<map>
<entry key="dict" value-ref="dict"/><!--在这里注册-->
</map>
</property>
<property name="templateLoaderPath" value="/WEB-INF"/>
<property name="freemarkerSettings">
<props>
<prop key="tag_syntax">square_bracket</prop>
<prop key="template_update_delay">0</prop>
<prop key="defaultEncoding">UTF-8</prop>
<prop key="url_escaping_charset">UTF-8</prop>
<prop key="locale">zh_CN</prop>
<prop key="boolean_format">true,false</prop>
<prop key="datetime_format">yyyy-MM-dd HH:mm:ss</prop>
<prop key="date_format">yyyy-MM-dd</prop>
<prop key="time_format">HH:mm:ss</prop>
<prop key="number_format">0.######</prop>
<prop key="classic_compatible">false</prop>
<prop key="whitespace_stripping">true</prop>
</props>
</property>
</bean>
最后就是使用了,例如在frl模板中这么使用: ${dict("edu","1")},${dict("marry","1")},其余的自己扩展吧,欢迎拍砖~!!!!
Over~!!

本文介绍了一种不依赖数据库的数据字典管理方案,通过XML文件存储键值对,并利用Java代码在系统启动时加载到内存中,方便后续使用。
342

被折叠的 条评论
为什么被折叠?



