2011-02-03 83 views
14

我需要根据数据库中的表创建一个枚举。如何动态创建枚举?

DB表MyColors:ID /标题/值 1 /红/ 1 2 /绿/ 4

动态创建

enum MyColors { 
    Red=1, 
    Green=4; 
} 
+5

这是一个矛盾的问题。枚举通常用于在运行时存在的实例。不过,我了解你的情况。我以类似的方式提出了一些问题:http://stackoverflow.com/questions/492096/persisting-data-suited-for-enums – 2011-02-03 19:02:10

+0

你究竟在做什么? - 如果你想在你的sql结果中用红色替换1,用绿色替换1,你可以做一个连接来显示相应的名称 – 2011-02-03 19:03:47

回答

11

可以通过从数据库中读取动态创建的源代码和只需输出一个有利于构建枚举的格式的结果即可。但是,在运行时创建枚举是不切实际的。你会更好用某种联合数组。

1

目前还不清楚您是否要生成源代码。我想不是,因为即使编译没有代码在同一个程序可以访问的枚举对象,除了通过反射。

那么为什么不使用JPA将表映射到ColorEntity对象呢? 然后,您可以获得这些实体或任何您需要的列表或地图。

2

一种选择是将XML Schema和所需的值定义为enum并生成类文件,以便我们可以管理源代码之外的值,但是我们不能动态生成数据库中的枚举值。

1
/** 
    * Add an enum instance to the enum class given as argument 
    * 
    * @param the type of the enum (implicit) 
    * @param enumType the class of the enum to be modified 
    * @param enumName the name of the new enum instance to be added to the class. 
    */ 
    @SuppressWarnings("unchecked") 
    public static <T extends Enum<?>> void addEnum(Class<T> enumType, String enumName) { 

     // 0. Sanity checks 
     if (!Enum.class.isAssignableFrom(enumType)) { 
      throw new RuntimeException("class " + enumType + " is not an instance of Enum"); 
     } 
     // 1. Lookup "$VALUES" holder in enum class and get previous enum instances 
     Field valuesField = null; 
     Field[] fields = enumType.getDeclaredFields(); 
     for (Field field : fields) { 
      if (field.getName().contains("$VALUES")) { 
       valuesField = field; 
       break; 
      } 
     } 
     AccessibleObject.setAccessible(new Field[] { valuesField }, true); 

     try { 

      // 2. Copy it 
      T[] previousValues = (T[]) valuesField.get(enumType); 
      List values = new ArrayList(Arrays.asList(previousValues)); 

      // 3. build new enum 
      T newValue = (T) makeEnum(enumType, // The target enum class 
        enumName, // THE NEW ENUM INSTANCE TO BE DYNAMICALLY ADDED 
        values.size(), 
        new Class<><[] {}, // can be used to pass values to the enum constuctor 
        new Object[] {}); // can be used to pass values to the enum constuctor 

      // 4. add new value 
      values.add(newValue); 

      // 5. Set new values field 
      setFailsafeFieldValue(valuesField, null, 
        values.toArray((T[]) Array.newInstance(enumType, 0))); 

      // 6. Clean enum cache 
      cleanEnumCache(enumType); 

     } catch (Exception e) { 
      e.printStackTrace(); 
      throw new RuntimeException(e.getMessage(), e); 
     } 
    } 

上面的代码可以帮助你。