最近接觸到數據字典的設計,網上找到點資料,原文鏈接:http://blog.csdn.net/stevene/article/details/575142?reload
在應用開發中,總會遇到許多數據字典項,比如對象狀態、對象類型等等,這些項一般都是固定的若干可選值選項,比如對象狀態可能有新建、修改、刪除等狀態,這些數據字典項一旦定義完畢改動的頻率非常低;在應用開發中,爲了處理方便,一般要對這些數據字典項值選項進行數字編碼(例如: 0表示新建,1表示修改,2表示刪除等),以方便應用程序中使用。而UI顯示對象信息時不能顯示對象狀態等的編碼,對於編碼值設計人員知道代表什麼意思,但用戶就不明白了,所以需要進行編碼轉換,從編碼轉換爲文字描述(名稱),也就是需要把狀態編碼0轉換爲“新建”,把1轉換爲“修改”,把2轉換爲“刪除”等顯示給用戶,用戶才明白對象當前的狀態是什麼。
下面介紹一下常用的實現方法:
一、在java文件中定義數據字典項
我們習慣上把應用中遇到的數據字典項都定義到一個java文件中,這是最常用的方法,實現起來比較簡單,但維護起來就非常繁瑣,特別是數據字典項比較多的情況下,相應的java文件就會比較大,一旦數據字典項有更新那麼維護起來就比較費時費力。
在java文件中定義數據字典項通常情況下定義爲static,舉例來說,類ReportConstants中定義了以下數據字典項:
public static final int CODE_USERINF_TECHELEVEL_GJ = 1;
public static final String CODE_USERINF_TECHELEVEL_GJ_KEY = "高級";
public static final int CODE_USERINF_TECHELEVEL_ZJ = 2;
public static final String CODE_USERINF_TECHELEVEL_ZJ_KEY = "中級";
public static final int CODE_USERINF_TECHELEVEL_CJ = 3;
public static final String CODE_USERINF_TECHELEVEL_CJ_KEY = "初級";
public static final int CODE_USERINF_TECHELEVEL_WJ = 4;
public static final String CODE_USERINF_TECHELEVEL_WJ_KEY = "無職稱";
那麼我們在實現中就可以直接引用相應的數據字典項編碼及名稱,另外,一般情況下需要定義數據字典項編碼和名稱的轉換方法,比如:public static String getCodeName(int lCode){
//初始化返回值
String strReturn = "未知";
switch (lCode){
case CODE_USERINF_TECHELEVEL_GJ :
strReturn = CODE_USERINF_TECHELEVEL_GJ_KEY;
break;
case CODE_USERINF_TECHELEVEL_ZJ :
strReturn = CODE_USERINF_TECHELEVEL_ZJ_KEY;
break;
case CODE_USERINF_TECHELEVEL_CJ :
strReturn = CODE_USERINF_TECHELEVEL_CJ_KEY;
break;
case CODE_USERINF_TECHELEVEL_WJ :
strReturn = CODE_USERINF_TECHELEVEL_WJ_KEY;
break;
}
return strReturn;
}
這個方法實現了通過數據字典項編碼獲得數據字典項名稱的功能。那麼還需要實現一個對應的方法,getCodeByName(String name),即通過數據字典項名稱獲取數據字典項編碼功能(代碼這裏省略)。這樣就可以實現數據字典項編碼和名稱的相互轉換。但是一旦出現數據字典項名稱或編碼需要更改(“無職稱”項編碼需要由“4”改爲“0”),或增加減少數據字典項,都需要更新java文件代碼。
二、在xml文件中定義
使用xml配置文件定義數據字典項,以便最大限度的減小維護的工作量,避免java代碼的頻繁修改。
下面我們分步驟詳細介紹一下使用xml配置文件的實現方案
第一步:定義xml數據字典項配置文件
首先新建一個xml文件,命名爲DataDictionaryConfig.xml(名字可以自己定義),把應用的用到的數據字典項分組定義到xml文件中,舉例如下,我們定義了下列數據字典項:
<?xml version="1.0" encoding="GB2312"?>
<data-dictionaries>
<data-dictionary>
<group value = "0" name="ObjectStatus">
<option value="0" name="detached"/>
<option value="1" name="new"/>
<option value="2" name="updated"/>
<option value="3" name="deleted"/>
</group>
<group value = "1" name="ObjectTypes">
<option value="0" name="對象類型選項0"/>
<option value="1" name="對象類型選項1"/>
<option value="2" name="對象類型選項2"/>
<option value="3" name="對象類型選項3"/>
</group>
</data-dictionary>
</data-dictionaries>
這個xml文件可以根據需要進行擴展,滿足更復雜應用的需要。第二步,定義數據字典項對象類和數據字典項分組對象類
對於數據字典項這裏我們定義了一個數據字典項對象類,一組數據字典選項集我們定義了一個數據字典項分組對象類,如下:
/**
*
* 數據字典項類
*
*/
public class DataDictionaryItem{
public DataDictionaryItem(){
}
private String code;
private String name;
public void setCode(String code){
this.code = code;
}
public String getCode(){
return this.code;
}
public void setName(String name){
this.name = name;
}
public String getName(){
return this.name;
}
}
/**
*
* 數據字典項分組類
*
*/
public class DataDictionaryItems{
private String groupCode;//數據字典項分組編碼
private String groupName;//數據字典項分組名稱
private java.util.ArrayList items;//數據字典項詳細
public DataDictionaryItems(){
}
public void setGroupCode(String code){
this.groupCode = code;
}
public String getGroupCoude(){
return this.groupCode;
}
public void setGroupName(String name){
this.groupName = name;
}
public String getGroupName(){
return this.groupName;
}
/*
* 設置數據字典項
*/
public void setDataDictionaryItem(DataDictionaryItem item){
if(this.items == null)
this.items = new java.util.ArrayList();
this.items.add(item);
}
/*
* 設置數據字典項
*/
public void setDataDictionaryItem(String itemName, String itemCode){
if(this.items == null)
this.items = new java.util.ArrayList();
DataDictionaryItem item = new DataDictionaryItem();
item.setCode(itemCode);
item.setName(itemName);
this.items.add(item);
}
/*
* 獲得數據字典項組對象
*/
public java.util.ArrayList getDataDictioanryItems(){
return this.items;
}
第三步,定義Xml數據字典項配置文件解析類,這裏我們使用Dom4J,相應的jar可以在http://www.dom4j.org/上找到
<span style="font-size:14px;">import org.dom4j.*;
import org.dom4j.io.*;
import java.util.*;
/**
* @author guoxk
*
* @version 創建時間 2015年11月18日 上午11:00:25
*
* 類描述:Xml數據字典項配置文件解析類
*/
public class XMLDDItemParser {
// 數據字典項結構
public static DataDictionaryItems dataItems;
private static String GROUP_NAME = "name";
private static String GROUP_CODE = "value";
private static String ITEM_NAME = "name";
private static String ITEM_CODE = "value";
public XMLDDItemParser() {
}
/**
* 獲得分組數據字典項集
*
* @param groupName
* String
* @return DataDictionaryItems
*/
public static DataDictionaryItems getDataDictionaryItems(String groupName) {
if (dataItems == null)
dataItems = parseXML(groupName);
return dataItems;
}
/**
* 根據分組名稱解析xml文件,獲得該分組下數據字典項集
*
* @param gName
* String
* @return DataDictionaryItems 數據字典項分組對象
*/
public static DataDictionaryItems parseXML(String gName) {
try {
org.dom4j.io.SAXReader saxReader = new org.dom4j.io.SAXReader();
Document document = saxReader.read("DataDictionaryConfig.xml");
dataItems = new DataDictionaryItems();
List list = document.selectNodes("//group");
Iterator iter = list.iterator();
while (iter.hasNext()) {
Node node = (Node) iter.next();
if (node instanceof Element) {
// document
Element element = (Element) node;
String GroupName = element.attributeValue(GROUP_NAME);
String GroupValue = element.attributeValue(GROUP_CODE);
// 設置分組名稱編碼
dataItems.setGroupName(GroupName);
dataItems.setGroupCode(GroupValue);
// 取組內數據字典項
if (gName.equals(GroupName)) {
// 取數據字典項名稱編碼
Iterator elemIter = element.elementIterator();
while (elemIter.hasNext()) {
Element elem = (Element) elemIter.next();
dataItems.setDataDictionaryItem(
elem.attributeValue(ITEM_NAME),
elem.attributeValue(ITEM_CODE));
}
}
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
return dataItems;
}
}</span>
第四步,提供數據字典項編碼轉換方法類
/**
* @author guoxk
*
* @version 創建時間 2015年11月18日 上午11:06:32
*
* 類描述:提供數據字典項編碼轉換方法類
*
*/
public class DataDictionaryUtils {
public DataDictionaryUtils() {
}
/**
* @author guoxk
*
* 方法描述:根據數據項名稱轉換爲數據項編碼
* @param groupName
* @param itemName
* @return String 數據項編碼
*/
public static String getItemCode(String groupName, String itemName) {
String code = "-1";
DataDictionaryItems dataItems = XMLDDItemParser
.getDataDictionaryItems(groupName);
java.util.ArrayList items = dataItems.getDataDictioanryItems();
if (items != null) {
DataDictionaryItem item;
for (int i = 0; i < items.size(); i++) {
item = (DataDictionaryItem) items.get(i);
if (item != null) {
String name = item.getName();
if (name.equals(itemName)) {
code = item.getCode();
break;
}
}
}
}
return code;
}
/**
* @author guoxk
*
* 方法描述:根據數據項編碼轉換爲數據項名稱
* @param groupName
* @param itemCode
* @return
*/
public static String getItemName(String groupName, String itemCode) {
String name = "未知";
DataDictionaryItems dataItems = XMLDDItemParser
.getDataDictionaryItems(groupName);
java.util.ArrayList items = dataItems.getDataDictioanryItems();
if (items != null) {
DataDictionaryItem item;
for (int i = 0; i < items.size(); i++) {
item = (DataDictionaryItem) items.get(i);
if (item != null) {
String code = item.getCode();
if (code.equals(itemCode)) {
name = item.getName();
break;
}
}
}
}
return name;
}
}
至此,我們已經完成了該方案的設計。使用xml文件,增加刪除數據字典項等只需要更新xml文件即可,不涉及java文件的更新。Xml可以根據應用的具體需要進行擴展設計。這裏僅僅拋磚引玉,提供一種思路。
三、使用數據庫表
現在我們把數據字典項定義在數據庫表中,下面我們來詳細介紹實現方式:
第一步:定義數據字典項數據表結構
根據前面xml文件定義,這裏我們定義兩張表,一張是數據字典分組信息表,一張是數據字典項詳細信息表。如下:
drop table datadic_groups;
create table datadic_groups(
group_code varchar2(20) primary key,
group_name varchar2(50)
);
drop table datadic_items;
create table datadic_items(
dataitem_code varchar2(20) primary key,
dataitem_name varchar2(50),
group_code varchar2(20)
);
alter table datadic_items
add constraint dataitem_foreignkey foreign key (group_code)
references datadic_groups(group_code);
這兩張表可以根據應用的具體需求進行擴充,這裏不再贅述。第二步:根據定義的數據字典表結構定義數據字典實體類。(請參照二、在xml文件中定義的第二步)
第三步:實現數據庫表中數據字典項的查詢功能
/**
* @author guoxk
*
* 方法描述:實現從數據庫查詢數據字典項
* @param gName
* @return
*/
public static DataDictionaryItems getFromDB(String gName) {
dataItems = new DataDictionaryItems();
try {
// 獲取數據連接
java.sql.Connection conn = getConnection();
if (conn != null) {
// 查詢數據庫,根據組名稱查詢組編號,根據組編號獲取該組內數據字典項信息
String strSql = "select items.dataitem_code, "
+ "items.dataitem_name, "
+ "items.group_code, "
+ "dgroups.group_name "
+ "from datadic_items items,"
+ " datadic_groups dgroups "
+ "where items.group_code = dgroups.group_code "
+ "and dgroups.group_name='"
+ gName + "'";
java.sql.Statement stmt = conn.createStatement();
java.sql.ResultSet rs = stmt.executeQuery(strSql);
while (rs.next()) {
String dataitem_code = rs.getString(1);
String dataitem_name = rs.getString(2);
dataItems.setDataDictionaryItem(dataitem_name,
dataitem_code);
String group_code = rs.getString(3);
String group_name = rs.getString(4);
dataItems.setGroupCode(group_code);
dataItems.setGroupName(group_name);
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
return dataItems;
}
第四步:提供數據字典項編碼轉換方法類(請參照二、在xml文件中定義的第四步)
四、進一步完善
1、兩種方式都可以提供數據字典項維護界面,直接在維護界面上操作數據字典項,避免由於誤操作導致xml文件或數據庫數據錯誤。具體的實現也是比較簡單,不再詳細說明。
2、使用數據庫表方式時,如果想減少頻繁查詢數據庫,可以將數據字典項信息在系統啓動後第一次訪問時加載內存中,如果數據字典項數據量比較大,可實現一自維護線程,採用最近最少使用算法,將頻繁使用的數據字典項駐留內存,將長期不用的數據字典項從內存中刪除,每次自動檢查內存中的數據字典項,如果存在則從內存中讀取,如果不存在則查詢數據庫,替換內存中最少使用的數據字典項。
3、增加運行日誌記錄,可以使用log4J來記錄運行日誌
五、數據庫中建立數據字典視圖[自己創建使用的數據字典]
Insert into XT_BDBMJG
(XT_BDBMJG_ZDLBNM, XT_BDBMJG_ZDLBMC, XT_BDBMJG_BMJG, XT_BDBMJG_SJCD, XT_BDBMJG_YLCD)
Values
('J_V_ZHZT', '賬戶狀態', '2', 2, 32);
Insert into XT_BDDMZB
(XT_BDDMZB_NM, XT_BDDMZB_ZDLBNM, XT_BDDMZB_BM, XT_BDDMZB_GGDMMC, XT_BDDMZB_SXH, XT_BDDMZB_ZT, XT_BDDMZB_JC, XT_BDDMZB_SFMX)
Values
('J_V_001', 'J_V_ZHZT', '01', '正常', 1, '1', '1', '1');
Insert into XT_BDDMZB
(XT_BDDMZB_NM, XT_BDDMZB_ZDLBNM, XT_BDDMZB_BM, XT_BDDMZB_GGDMMC, XT_BDDMZB_SXH, XT_BDDMZB_ZT, XT_BDDMZB_JC, XT_BDDMZB_SFMX)
Values
('J_V_002', 'J_V_ZHZT', '02', '凍結', 2, '1', '1', '1');
Insert into XT_BDDMZB
(XT_BDDMZB_NM, XT_BDDMZB_ZDLBNM, XT_BDDMZB_BM, XT_BDDMZB_GGDMMC, XT_BDDMZB_SXH, XT_BDDMZB_ZT, XT_BDDMZB_JC, XT_BDDMZB_SFMX)
Values
('J_V_003', 'J_V_ZHZT', '03', '註銷', 3, '1', '1', '1');
Insert into XT_TYKJ
(XT_TYKJ_KJBH, XT_TYKJ_KJMC, XT_TYKJ_KJLX, XT_TYKJ_KJBM, XT_TYKJ_KJBT, XT_TYKJ_MCZD, XT_TYKJ_NMZD, XT_TYKJ_CXTJ, XT_TYKJ_CATCH)
Values
('1000059', 'J_V_ZHZT', 'L', 'XT_BDDMZB', '賬戶狀態','XT_BDDMZB_GGDMMC','XT_BDDMZB_BM','XT_BDDMZB_ZDLBNM=''J_V_ZHZT'' ', 'N');
CREATE OR REPLACE VIEW J_DIC_ZHZT
(DM, MC)
AS
SELECT xt_bddmzb_bm AS dm, xt_bddmzb_ggdmmc AS mc
FROM xt_bddmzb
WHERE xt_bddmzb_zdlbnm = 'J_V_ZHZT';
Insert into DC_SYS_DIC
(TABLE_ID, TABLE_NAME, DATAID_COL, DATANAME_COL)
Values
('J_DIC_ZHZT', '賬戶狀態', 'DM', 'MC');</span>