2011-02-03 87 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); 
     } 
    } 

上面的代碼可以幫助你。