将枚举保存到数据库中的最佳方法是什么?
我知道Java提供name()和valueOf()方法来枚举值转换为字符串和背部。但是还有其他(灵活的)选项来存储这些值吗?
name()
valueOf()
有没有一种聪明的方法可以使枚举成为唯一的数字(ordinal()使用不安全)?
ordinal()
更新:
感谢您提供的所有出色且快速的答案!就像我怀疑的那样。
但是要注意“工具包”;那是一种方式。问题是我必须向创建的每个Enum类型添加相同的方法。那就是很多重复的代码,并且目前Java不支持任何解决方案(Java枚举不能扩展其他类)。
我们 再也不会 将枚举存储为数字序数值了。这使得调试和支持方式太困难了。我们存储转换为字符串的实际枚举值:
public enum Suit { Spade, Heart, Diamond, Club } Suit theSuit = Suit.Heart; szQuery = "INSERT INTO Customers (Name, Suit) " + "VALUES ('Ian Boyd', %s)".format(theSuit.name());
然后回读:
Suit theSuit = Suit.valueOf(reader["Suit"]);
该问题过去一直盯着企业管理器并试图破译:
Name Suit ================== ========== Shelby Jackson 2 Ian Boyd 1
经文
Name Suit ================== ========== Shelby Jackson Diamond Ian Boyd Heart
后者要容易得多。前者需要获取源代码并查找分配给枚举成员的数值。
是的,它需要更多的空间,但是枚举成员的名称很短,而硬盘驱动器很便宜,如果遇到问题,可以提供更多帮助。
此外,如果使用数值,则将它们绑定在一起。您不必强制使用旧的数值就无法很好地插入或重新排列成员。例如,将Suit枚举更改为:
public enum Suit { Unknown, Heart, Club, Diamond, Spade }
必须成为:
public enum Suit { Unknown = 4, Heart = 1, Club = 3, Diamond = 2, Spade = 0 }
为了维护存储在数据库中的旧数值。
问题来了:可以说我想对值进行排序。有些人可能想按枚举的序数对它们进行排序。当然,按枚举的数值对卡片排序是没有意义的:
SELECT Suit FROM Cards ORDER BY SuitID; --where SuitID is integer value(4,1,3,2,0) Suit ------ Spade Heart Diamond Club Unknown
那不是我们想要的顺序-我们希望它们按枚举顺序:
SELECT Suit FROM Cards ORDER BY CASE SuitID OF WHEN 4 THEN 0 --Unknown first WHEN 1 THEN 1 --Heart WHEN 3 THEN 2 --Club WHEN 2 THEN 3 --Diamond WHEN 0 THEN 4 --Spade ELSE 999 END
如果保存字符串,则需要执行与保存整数值相同的工作:
SELECT Suit FROM Cards ORDER BY Suit; --where Suit is an enum name Suit ------- Club Diamond Heart Spade Unknown
但这不是我们想要的顺序-我们希望它们按枚举顺序:
SELECT Suit FROM Cards ORDER BY CASE Suit OF WHEN 'Unknown' THEN 0 WHEN 'Heart' THEN 1 WHEN 'Club' THEN 2 WHEN 'Diamond' THEN 3 WHEN 'Space' THEN 4 ELSE 999 END
我认为这种排名属于用户界面。如果您要根据项目的枚举值对项目进行排序:您做错了什么。
但是,如果您想真正做到这一点,我将创建一个Suits尺寸表:
Suits
| Suit | SuitID | Rank | Color | |------------|--------------|---------------|--------| | Unknown | 4 | 0 | NULL | | Heart | 1 | 1 | Red | | Club | 3 | 2 | Black | | Diamond | 2 | 3 | Red | | Spade | 0 | 4 | Black |
这样,当您想更改卡以使用“ 接吻王” 新卡牌 定单时 ,可以出于显示目的进行更改,而不会丢弃所有数据:
| Suit | SuitID | Rank | Color | CardOrder | |------------|--------------|---------------|--------|-----------| | Unknown | 4 | 0 | NULL | NULL | | Spade | 0 | 1 | Black | 1 | | Diamond | 2 | 2 | Red | 1 | | Club | 3 | 3 | Black | -1 | | Heart | 1 | 4 | Red | -1 |
现在,我们将内部编程详细信息(枚举名称,枚举值)与显示设置分开,以供用户使用:
SELECT Cards.Suit FROM Cards INNER JOIN Suits ON Cards.Suit = Suits.Suit ORDER BY Suits.Rank, Card.Rank*Suits.CardOrder