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

时间:2009-05-12 06:46:11

标签: hashmap enumeration java

我有一张表格,它映射了String-> Integer。

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

所以,而不是静态地删除这个:

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

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

6 个答案:

答案 0 :(得分:30)

没有。枚举总是在编译时固定。你能做到这一点的唯一方法是动态生成相关的字节码。

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

如果你真的只想要一张从StringInteger的地图,你可以使用你在执行时填充的Map<String, Integer>,然后你就完成了。如果你想要EnumSet功能,那么以相同的效率再现它们会有点棘手,但是通过一些努力它可能是可行的。

所以,在进一步考虑实施之前,我建议你弄清楚你的实际需求是什么。

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

答案 1 :(得分:23)

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

尽管我重视他的答案,但我认为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;
    }
}

答案 2 :(得分:6)

改进what Andreas did,您可以将数据库的内容加载到地图中,以减少所需的数据库连接数。

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); }
    }
}

答案 3 :(得分:3)

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

另请参阅Stack Overflow问题 Dynamic enum in C#

答案 4 :(得分:1)

您需要在代码中复制数据库中的内容(反之亦然)。有关一些好的建议,请参阅此question

答案 5 :(得分:0)

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

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