使用数据库中的值填充枚举
2022-09-01 13:46:49
我有一个映射String->Integer的表。
我不想静态地创建枚举,而是要用数据库中的值填充枚举。这可能吗?
所以,而不是静态地去关心这一点:
public enum Size { SMALL(0), MEDIUM(1), LARGE(2), SUPERSIZE(3) };
我想动态创建这个枚举,因为数字{0,1,2,3}基本上是随机的(因为它们是由数据库的AUTOINCREMENT列自动生成的)。
我有一个映射String->Integer的表。
我不想静态地创建枚举,而是要用数据库中的值填充枚举。这可能吗?
所以,而不是静态地去关心这一点:
public enum Size { SMALL(0), MEDIUM(1), LARGE(2), SUPERSIZE(3) };
我想动态创建这个枚举,因为数字{0,1,2,3}基本上是随机的(因为它们是由数据库的AUTOINCREMENT列自动生成的)。
不。枚举始终在编译时是固定的。执行此操作的唯一方法是按顺序生成相关的字节码。
话虽如此,您可能应该弄清楚您真正感兴趣的枚举的哪些方面。大概你不想在它们上使用语句,因为这意味着静态代码,你不知道静态的值......同样,代码中的任何其他引用也是如此。switch
如果你真的只是想要一个从 到 的映射,你可以使用一个在执行时填充的映射,你就完成了。如果您想要这些功能,以相同的效率复制它们会有些棘手,但是通过一些努力可能是可行的。StringIntegerMap<String, Integer>EnumSet
因此,在进一步考虑实现之前,我建议您弄清楚您的真正需求是什么。
(编辑:我一直假设这个枚举是完全动态的,即你不知道名称,甚至不知道有多少个值。如果这组名称是固定的,并且您只需要从数据库中获取ID,那就是一个非常不同的问题 - 请参阅Andreas的答案。
这有点棘手,因为这些值的填充发生在类加载时间。因此,您将需要对数据库连接进行静态访问。
尽管我很看重他的答案,但我认为乔恩·斯基特这次可能是错的。
看看这个:
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;
}
}