Java 使用数据库中的值填充枚举
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/851466/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Populate an enum with values from database
提问by Jacques René Mesrine
I have a table which maps String->Integer.
我有一个映射 String->Integer 的表。
Rather than create an enum statically, I want to populate the enum with values from a database. Is this possible ?
我想用数据库中的值填充枚举,而不是静态创建枚举。这可能吗 ?
So, rather than delcaring this statically:
所以,而不是静态地声明它:
public enum Size { SMALL(0), MEDIUM(1), LARGE(2), SUPERSIZE(3) };
I want to create this enum dynamically since the numbers {0,1,2,3} are basically random (because they are autogenerated by the database's AUTOINCREMENT column).
我想动态创建这个枚举,因为数字 {0,1,2,3} 基本上是随机的(因为它们是由数据库的 AUTOINCREMENT 列自动生成的)。
采纳答案by Jon Skeet
No. Enums are always fixed at compile-time. The only way you could do this would be to dyamically generate the relevant bytecode.
不。枚举总是在编译时固定的。您可以执行此操作的唯一方法是动态生成相关字节码。
Having said that, you should probably work out which aspects of an enum you're actually interested in. Presumably you weren't wanting to use a switch
statement over them, as that would mean static code and you don't know the values statically... likewise any other references in the code.
话虽如此,您可能应该弄清楚您真正感兴趣的枚举的哪些方面。大概您不想对switch
它们使用语句,因为这意味着静态代码,并且您不知道静态值。 .. 代码中的任何其他引用也是如此。
If you really just want a map from String
to Integer
, you can just use a Map<String, Integer>
which you populate at execution time, and you're done. If you want the EnumSet
features, they would be somewhat trickier to reproduce with the same efficiency, but it may be feasible with some effort.
如果你真的只想要一个从String
to的映射Integer
,你可以只使用Map<String, Integer>
你在执行时填充的a ,你就完成了。如果您想要这些EnumSet
功能,以相同的效率重现它们会有些棘手,但通过一些努力可能是可行的。
So, before going any further in terms of thinking about implementation, I suggest you work out what your real requirements are.
因此,在考虑实施之前,我建议您先弄清楚您的真正需求是什么。
(EDIT: I've been assuming that this enum is fully dynamic, i.e. that you don't know the names or even how many values there are. If the set of names is fixed and you onlyneed to fetch the ID from the database, that's a very different matter - see Andreas' answer.)
(编辑:我一直假设这个枚举是完全动态的,即你不知道名称,甚至不知道有多少个值。如果名称集是固定的,你只需要从数据库中获取 ID ,这是一个非常不同的问题 - 请参阅安德烈亚斯的回答。)
回答by aleemb
Enums are not dynamic, so the short answer is that you can't do it.
枚举不是动态的,所以简短的回答是你不能这样做。
Also have a look at Stack Overflow question Dynamic enum in C#.
另请查看 Stack Overflow 问题Dynamic enum in C#。
回答by Luixv
In all the languages I know enums are static. The compiler can make some optimizations on them. Therefore the short answer is no, you can't.
在我知道的所有语言中,枚举都是静态的。编译器可以对它们进行一些优化。因此,简短的回答是否定的,你不能。
The question is why you want to use an enum in this way. What do you expect? Or in other words why not use a collection instead?
问题是为什么要以这种方式使用枚举。你能指望什么?或者换句话说,为什么不使用集合呢?
回答by Andreas Petersson
This is a bit tricky, since the population of those values happens at class-load time. So you will need a static access to a database connection.
这有点棘手,因为这些值的填充发生在类加载时。因此,您将需要对数据库连接进行静态访问。
As much as I value his answers, I think Jon Skeet may be wrong this time.
尽管我很看重他的回答,但我认为 Jon Skeet 这次可能是错的。
Take a look at this:
看看这个:
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;
}
}
回答by kgiannakakis
回答by Tigertron
Improving on what Andreas did, you can load the contents of the database into a map to reduce the number of database connections needed.
改进Andreas 所做的事情,您可以将数据库的内容加载到地图中以减少所需的数据库连接数。
public enum DbEnum {
FIRST(getFromDb("FIRST")),
SECOND(getFromDb("second"));
private Map<String,Integer> map;
private static int getFromDB(String s)
{
if (map == null)
{
map = new HashMap<String,Integer>();
// 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); }
}
}