gpt4 book ai didi

java - 使用描述和键保存枚举 - MySQL 和 Java

转载 作者:行者123 更新时间:2023-12-02 11:35:52 25 4
gpt4 key购买 nike

我有一个枚举如下

public enum OrderStatusEnum {
ACTIVE("A","Active Order"),
AWAITING("I","Awaiting Order")
}

我想将 ACTIVE, AWAITING 保存在数据库中。还可以在查询中检索相同的内容

当实体设置为枚举并通过 JdbcTemplate 保存时,我遇到异常。数据截断异常

问题

  1. 我需要将 ACTIVE/AWAITING 保存到数据库或 Active Order/Awaiting Order 中吗?
  2. 如何使用 JdbcTemplate 使用 native SQL 查询保存枚举值

我们正在使用MapSqlParameterSource

谢谢。

最佳答案

1) 您可以存储“ACTIVE/AWAITING”并使用枚举的 valueOf 方法。

优点:

  1. 无需为映射方法编写额外代码 - 使用标准enumvalueOf
  2. 数据库中的值更易于理解
  3. 所有枚举的常量名称都必须是唯一的,因此消除了此类错误

缺点:

  1. 数据库中可能有更多空间来存储这些值
  2. 重命名枚举常量将导致需要更新数据库记录

例如:

将数据插入表中:

jdbcTemplate.update(
"INSERT INTO orders (id, order_status, description) VALUES (?, ?, ?)",
new Object[] {
order.getId(),
order.getStatus().toString(),
order.getDescription()
}
);

加载数据:

public List<Order> findAllOrders() 
{
return jdbcTemplate.query(
"SELECT * FROM orders",
new String[]{},
(rs, rowNum) -> new Order(rs.getInt("id"), OrderStatus.valueOf(rs.getString("order_status")), rs.getString("description"))
);
}

这里的巧妙之处在于,您不需要编写 valueOf 方法,它存在于任何枚举中,请参阅 https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html#valueOf-java.lang.Class-java.lang.String-

2) 您可以使用 shortName(例如“A”),但您需要遍历所有枚举才能找到正确的枚举。

优点:

  1. 数据库中存储这些值的空间可能更少

缺点:

  1. 需要为映射方法编写额外的代码
  2. 数据库中的值远不便于人类阅读
  3. 有可能添加 2 个具有相同短名称的枚举常量,这将导致数据损坏

例如:

要保存,请使用order.getStatus().getShortName()
对于加载使用:getStatus(rs.getString("order_status")):

private OrderStatus getStatus(String shortName)
{
switch(shortName)
{
case "A":
return OrderStatus.ACTIVE;
case "I":
return OrderStatus.AWAITING;
default:
throw new RuntimeException("Cannot find order status for short name: " + shortName);
}
}

更新:OrderStatus枚举声明:

public enum OrderStatus
{
ACTIVE("A","Active Order"),
AWAITING("I","Awaiting Order");

private String shortName;
private String description;

private OrderStatus(String shortName, String description)
{
this.shortName = shortName;
this.description = description;
}

public String getShortName()
{
return shortName;
}

public String getDescription()
{
return description;
}
}

更新 2:OrderStatus 与其所需的数据库表示之间的映射应由您明确进行。如果您想使用 shortName 进行映射,您应该以某种方式在代码中表达它,否则它如何知道您想如何映射它?您可以使用另一种映射方式,这意味着存在不同的方法。例如,有一种方法可以保存 OrderStatus.ordinal(),然后使用 OrderStatus.values()[rs.getInt("order_status")] 对其进行转换。在这种情况下,您可能会使用更少的空间来存储值,具体取决于您的 DBMS,但如果您添加更多枚举常量,现有常量可能会为 OrderStatus.SOME_ENUM_CONSTANT.ordinal() 获得不同的值,这会导致数据损坏或需要更新数据库中的旧记录,然后启动新版本的应用程序,这就是为什么我没有将此选项包含在映射选项列表中。

关于java - 使用描述和键保存枚举 - MySQL 和 Java,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48950919/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com