• 应用开发中数据字典项设计实现方案


     

    应用开发中数据字典项设计实现方案

    在 应用开发中,总会遇到许多数据字典项,比如对象状态、对象类型等等,这些项一般都是固定的若干可选值选项,比如对象状态可能有新建、修改、删除等状态,这 些数据字典项一旦定义完毕改动的频率非常低;在应用开发中,为了处理方便,一般要对这些数据字典项值选项进行数字编码(例如: 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文件代码。是否有简便的方法在满足上述需求的情况下又不更新java文件代码?答案是肯定的。下面我们来介绍两种实现方法:一中使用xml文件,一种在数据库定义。

    二、在xml文件中定义

    第一种方案是应用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"/>

    <option value="4" name="对象类型选项4"/>

          </group>

        </data-dictionary>

    </data-dictionaries>

    这个xml文件可以根据需要进行扩展,满足更复杂应用的需要。

    第二步,定义数据字典项对象类和数据字典项分组对象类:

        对于数据字典项这里我们定义了一个数据字典项对象类,一组数据字典选项集我们定义了一个数据字典项分组对象类,如下:

    1)、数据字典项类:

    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;

      }

    }

    2)、数据字典项分组类

    public class DataDictionaryItems

    {

      public DataDictionaryItems()

      {

      }

      //数据字典项分组编码

      private String groupCode;

      //数据字典项分组名称

      private String groupName;

      //数据字典项详细

      private java.util.ArrayList items;

      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/上找到

    import org.dom4j.*;

    import org.dom4j.io.*;

    import java.util.*;

    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;

      }

    第四步,提供数据字典项编码转换方法类:

    public class DataDictionaryUtils {

      public DataDictionaryUtils() {

      }

      /**

       * 根据数据项名称转换为数据项编码

       * @param groupName String

       * @param itemName String

       * @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;

      }

      /**

       * 根据数据项编码转换为数据项名称

       * @param groupName String

       * @param itemCode String

       * @return String

       */ 

      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文件定义数据字典项,现在我们把数据字典项定义在数据库表中,下面我们来详细介绍实现方式:

    第一步:定义数据字典项数据表结构

    根据前面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文件中定义的第二步)

    第三步:实现数据库表中数据字典项的查询功能

      /**

       * 实现从数据库查询数据字典项

       * @param gName String

       * @return DataDictionaryItems

       */

      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来记录运行日志

  • 相关阅读:
    《JAVA设计模式》之模板模式(Template)
    《JAVA设计模式》之策略模式(Strategy)
    《JAVA设计模式》之享元模式(Flyweight)
    《JAVA设计模式》之桥接模式(Bridge)
    《JAVA设计模式》之组合模式(Composite)
    《JAVA设计模式》之外观模式(Facade)
    《JAVA设计模式》之代理模式(Proxy)
    《JAVA设计模式》之装饰模式(Decorator)
    《JAVA设计模式》之适配器模式(Adapter)
    《JAVA设计模式》之原型模式(Prototype)
  • 原文地址:https://www.cnblogs.com/toSeeMyDream/p/4380662.html
Copyright © 2020-2023  润新知