当前位置: 首页 > 面试题库 >

控制Hibernate EnumType.STRING属性的排序顺序

仲孙经赋
2023-03-14
问题内容

当前,我的项目使用@Enumerated(EnumType.ORDINAL),因此当我按此列排序时,它是根据中的顺序进行排序的enum,效果很好。但是我需要在中添加一些enum附加值,这些附加值需要插入到枚举值列表中的不同位置,并且不能仅仅添加到底部以保持正确的排序顺序。

如果这样做,我的数据库将会混乱。我将不得不编写一些脚本来将所有这些序数值转换为正确的新序数。有可能以后必须添加更多状态。由于必须修复数据库中的所有数据,因此只需要执行一次,因为这将是一项艰巨的任务。

因此,我正在考虑切换为EnumType.STRING不必再次重新映射数据库中的序数值。但是,如果我这样做,该如何正确排序?枚举字符串的字母顺序不是我需要的顺序。

使用下面的类,当我按属性“状态”排序时,结果按此顺序显示:

hql = "from Project order by status"

Development
Planning
Production

我希望它们按此顺序出现,而不使用EnumType.ORDINAL

Planning
Development
Production

无需为创建表格enum或为Project该类添加其他列,是否可以实现?我已经尝试过了,但是抛出了一个异常:

hql = "from Project order by status.sort"

枚举:

public enum Status {

    PLANNING("Planning", 0),
    DEVELOPMENT("Development", 1),
    PRODUCTION("Production", 2);

    private final String name;
    private final int sort;
    private Status(String name, int sort) {
        this.name = name;
        this.sort = sort;
    }
    @Override
    public String toString() {
        return name;
    }
}

实体:

@Entity
public class Project {
    private Long id;
    private Status status;

    @Id
    @GeneratedValue
    public Long getId() {
        return this.id;
    }
    private void setId(Long id) {
        this.id = id;
    }
    @Enumerated(EnumType.STRING)
    public Status getStatus() {
        return status;
    }
    public void setStatus(Status status) {
        this.status = status;
    }
}

问题答案:

因此,我正在考虑切换到EnumType.STRING,而不必再次重新映射数据库中的序数值。但是,如果我这样做,该如何正确排序?枚举字符串的字母顺序不是我需要的顺序。

我个人完全避免使用邪恶,EnumType.ORDINAL因为仅更改常量的顺序会破坏持久性逻辑。邪恶。话虽如此,EnumType.STRING确实并不总是适当的。

在您的情况下,这就是我要执行的操作(使用标准JPA):我将int在实体级别上坚持并在getter /
setter中执行枚举转换。这样的东西。首先,枚举:

public enum Status {
    PLANNING("Planning", 100),
    DEVELOPMENT("Development", 200),
    PRODUCTION("Production", 300);

    private final String label;
    private final int code;

    private Status(String label, int code) {
        this.label = label;
        this.code = code;
    }

    public int getCode() { return this.code; }

    private static final Map<Integer,Status> map;
    static {
        map = new HashMap<Integer,Status>();
        for (Status v : Status.values()) {
            map.put(v.code, v);
        }
    }
    public static Status parse(int i) {
        return map.get(i);
    }
}

因此,基本上,这个主意是能够通过获得Statuscode。并且我们在常量之间保留一些空间,以便可以添加值(虽然它不是很漂亮,但是,它将起作用并且应该在一段时间内是安全的)。

然后在实体中:

@Entity
public class Project {
    private Long id;
    private int statusCode;

    @Id @GeneratedValue
    public Long getId() {
        return this.id;
    }
    private void setId(Long id) {
        this.id = id;
    }

    @Transient
    public Status getStatus () {
        return Status.parse(this.statusCode);
    }
    public void setStatus(Status status) {
        this.statusCode = status.getCode();
    }

    protected int getStatusCode() {
        return statusCode;
    }
    protected void setStatusCode(int statusCode) {
        this.statusCode = statusCode;
    }
}

int表示的获取器/设置器受到保护。公共获取者/设置者处理转换。

另一种解决方案是使用自定义类型(以可移植性为代价)。



 类似资料:
  • 问题内容: 我正在从SQL Server查询生成XML文件。 我对元素排序有一些疑问。 例如,有下面的简单代码。 如您所见,树和树顺序是不同的元素,我想按属性排序 像这样。 任何人都有解决这个问题的好主意吗? 谢谢你。 对不起,我有以下详细问题 AS是 成为 : 谢谢你。 问题答案: 如果要重新排序现有的xml,可以使用: 结果: 更新: 要对多个节点重新排序,可以使用XQuery,如下所示: 更

  • 当使用Angular keyvalue管道遍历对象的属性时,如下所示: 我遇到过一个问题,即属性没有按照预期的顺序迭代。这条评论表明,我不是唯一一个经历过这个问题的人: 如何在Angular中使用ngFor循环对象属性

  • 问题内容: 我必须对具有多个属性的列表进行排序。我可以轻松地按升序对所有属性执行此操作 但是问题是,我必须使用混合配置来进行升序/降序…我必须“模仿”一点SQL ,在SQL中您可以执行类似的操作。有没有一种方法可以在Python中轻松实现,而无需实现自定义比较功能? 问题答案: 如果您的属性是数字,则具有此属性。 如果您的属性包括字符串或其他更复杂的对象,则可以选择。 该方法很稳定:您可以进行多次

  • 有没有办法在java中对Properties对象进行排序? 我有一个字符串,用于对属性进行分组,并检查数据是否以映射格式可用。

  • 问题内容: 我有一个XML编写脚本,可以为特定的第三方工具输出XML。 我已经使用原始XML作为模板来确保构建所有正确的元素,但是最终的XML看起来并不像原始XML。 我以相同的顺序编写属性,但是lxml以自己的顺序编写属性。 我不确定,但是我怀疑第3部分工具希望属性按特定顺序显示,并且我想解决此问题,以便查看其属性顺序是否导致失败,或其他原因。 源元素: 我的源脚本: 我生成的XML: 有没有办

  • 3.1 顺序控制结构 程序是一个语句序列,执行程序就是按特定的次序执行程序中的语句。程序中执行点的 变迁称为控制流程,当执行到程序中的某一条语句时,也说控制转到了该语句。由于复杂问 题的解法可能涉及复杂的执行次序,因此编程语言必须提供表达复杂控制流程的手段,称为 编程语言的控制结构。 程序的控制流程可以用流程图(flowchart)来形象地表示。流程图采用标准化的图形符 号来描述程序的执行步骤,是