Tau*_*ren 6 java orm enums hibernate hql
目前,我的项目使用@Enumerated(EnumType.ORDINAL),所以当我按此列排序时,它是根据订单中的顺序排序enum,这很好.但是我需要添加一些额外的值enum,这些值需要插入枚举值列表中的不同位置,并且不能只是添加到底部以保持正确的排序顺序.
如果我这样做,我的数据库将被搞砸.我将不得不编写一些脚本来将所有这些序数值转换为正确的新序数.以后可能需要添加更多状态.因为我必须修复数据库中的所有数据,所以我只想做一次,因为这将是一项艰巨的任务.
所以我想切换到EnumType.STRING不必再次重新映射数据库中的序数值.但是,如果我这样做,那我该怎么排序呢?枚举字符串的字母顺序不是我需要的顺序.
使用下面的类,当我按属性"status"排序时,结果按以下顺序排列:
hql = "from Project order by status"
Development
Planning
Production
Run Code Online (Sandbox Code Playgroud)
我希望他们按此顺序出来,不使用EnumType.ORDINAL:
Planning
Development
Production
Run Code Online (Sandbox Code Playgroud)
如果没有为该类创建表enum或向Project该类添加其他列,是否可以这样做?我试过这个,但它引发了一个异常:
hql = "from Project order by status.sort"
Run Code Online (Sandbox Code Playgroud)
枚举:
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;
}
}
Run Code Online (Sandbox Code Playgroud)
实体:
@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;
}
}
Run Code Online (Sandbox Code Playgroud)
所以我想切换到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);
}
}
Run Code Online (Sandbox Code Playgroud)
所以基本上,这个想法是能够Status通过它得到一个code.并且我们在常量之间保留一些空间,以便可以添加值(它不是很漂亮但是,它会起作用并且应该在一段时间内保持安全).
然后在实体中:
@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;
}
}
Run Code Online (Sandbox Code Playgroud)
表示的getter/setter int受到保护.公共getter/setter处理转换.
另一种解决方案是使用自定义类型(以便携性为代价).
| 归档时间: |
|
| 查看次数: |
5171 次 |
| 最近记录: |