数据字典设计

最近接触到数据字典的设计,网上找到点资料,原文链接: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>



评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值