使用描述和密钥保存枚举-MySQL和Java

使用描述和密钥保存枚举-MySQL和Java,java,spring,Java,Spring,我有一个枚举如下 public enum OrderStatusEnum { ACTIVE("A","Active Order"), AWAITING("I","Awaiting Order") } 我想保存活动,在数据库中等待。也可以在查询中检索相同的内容 当实体被设置为枚举并通过JdbcTemplate保存时,我面临异常。数据截断异常 问题 我是否需要在数据库中保存活动/等待订单或活动订单/等待订单? 如何使用JdbcTemplate使用本机SQL查询保存枚举值 我们正在使

我有一个枚举如下

public enum OrderStatusEnum {
    ACTIVE("A","Active Order"),
    AWAITING("I","Awaiting Order")
}
我想保存活动,在数据库中等待。也可以在查询中检索相同的内容

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

问题

我是否需要在数据库中保存活动/等待订单或活动订单/等待订单? 如何使用JdbcTemplate使用本机SQL查询保存枚举值 我们正在使用MapSqlParameterSource


谢谢。

1您可以存储'ACTIVE/waiting'并使用enum方法的valueOf。 优点:

无需为映射方法编写其他代码-使用标准 枚举的值。 数据库中的值更易于人类阅读 所有枚举的常量名称都必须是唯一的,因此消除了这种类型的错误 缺点:

在数据库中存储这些值可能需要更多的空间 重命名枚举常量将导致需要更新数据库记录 例如:

将数据插入表:

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"))
    );
}
更新: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.getIntorder_status]对其进行转换。在这种情况下,您可能会根据DBMS使用更少的空间来存储值,但如果要添加更多枚举常量,现有常量可能会获得OrderStatus.SOME_enum_CONSTANT.ordinal的不同值,这会导致数据损坏或需要更新数据库中的旧记录,然后启动新版本的应用程序,这就是为什么我没有将此选项包括在映射选项列表中。

请您共享toString的代码和valueOf。因为如果我传递addValueorderStatus、OrderStatusEnum.Waiting,则会出现数据截断错误。valueOf抛出错误。枚举定义的代码段将很有用。它在线程主java.lang.IllegalArgumentException中作为异常抛出错误:没有枚举常量com.mkyong.model.OrderStatusEnum.Waiting,当调用valueOf时。为了保存,您说要使用短名称,在上面的插入sql中您提到order.getStatus.toString,你能分享shortName、toString和valueOf方法的代码吗?这样就清楚了。你可以通过以下方式修复数据截断错误:1更改YOR数据库中enum的字段最大长度,即状态varchar20;2使用第二种方法:shortName。valueOf期望处于活动或等待状态,否则将抛出错误。toString是标准enum的方法。您可以检查此代码的输出:System.out.printlntoString:+OrderStatus.ACTIVE.toString;OrderStatus状态=OrderStatus.valueOfACTIVE;System.out.printlnShort name:+status.getShortName;
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;
    }   
}