使用数据库中的值填充枚举

我有一个映射String-> Integer的表。

我想用数据库中的值填充枚举,而不是静态创建枚举。 这可能吗 ?

所以,而不是静态地揭示这个:

public enum Size { SMALL(0), MEDIUM(1), LARGE(2), SUPERSIZE(3) }; 

我想动态创建这个枚举,因为数字{0,1,2,3}基本上是随机的(因为它们是由数据库的AUTOINCREMENT列自动生成的)。

编号时,枚举始终是固定的。 你能做到这一点的唯一方法是动态生成相关的字节码。

话虽如此,你应该弄清楚你真正感兴趣的枚举的哪些方面。大概你不想在它们上面使用switch语句,因为这意味着静态代码并且你不会静态地知道这些值……同样代码中的任何其他引用。

如果你真的只想要一个从StringInteger的映射,你可以使用你在执行时填充的Map ,你就完成了。 如果你想要EnumSetfunction,那么以相同的效率再现它们会有些棘手,但是通过一些努力可能是可行的。

因此,在考虑实施之前,我建议您先了解一下您的实际需求。

(编辑:我一直在假设这个枚举是完全动态的,即你不知道名字甚至知道有多少个值。如果名称集是固定的,你只需要从数据库中获取ID ,这是一个非常不同的问题 – 请参阅Andreas的回答 。)

这有点棘手,因为这些值的数量发生在类加载时。 因此,您需要静态访问数据库连接。

尽管我重视他的答案,但我认为Jon Skeet这次可能是错的。

看看这个:

 public enum DbEnum { FIRST(getFromDb("FIRST")), SECOND(getFromDb("second")); private static int getFromDb(String s) { PreparedStatement statement = null; ResultSet rs = null; try { Connection c = ConnectionFactory.getInstance().getConnection(); statement = c.prepareStatement("select id from Test where name=?"); statement.setString(1, s); rs = statement.executeQuery(); return rs.getInt(1); } catch (SQLException e) { throw new RuntimeException("error loading enum value for "+s,e); } finally { try { rs.close(); statement.close(); } catch (SQLException e) { //ignore } } throw new IllegalStateException("have no database"); } final int value; DbEnum(int value) { this.value = value; } } 

改进Andreas的function ,您可以将数据库的内容加载到映射中,以减少所需的数据库连接数。

 public enum DbEnum { FIRST(getFromDb("FIRST")), SECOND(getFromDb("second")); private Map map; private static int getFromDB(String s) { if (map == null) { map = new HashMap(); // Continue with database code but get everything and // then populate the map with key-value pairs. return map.get(s); } else { return map.get(s); } } } 

枚举不是动态的,所以简短的回答是你做不到。

另请参阅C#中的Stack Overflow问题动态枚举

您需要在代码中复制数据库中的内容(反之亦然)。 请参阅此问题以获得一些好的建议。

在所有语言中,我知道枚举是静态的。 编译器可以对它们进行一些优化。 因此简短的答案是否定的,你不能。

问题是为什么你想以这种方式使用枚举。 你能指望什么? 或者换句话说为什么不使用集合呢?