jpa 枚举字段的自定义排序顺序

r55awzrz  于 2023-10-19  发布在  其他
关注(0)|答案(3)|浏览(124)

是否可以将JPA中的字母排序改为自定义?
我在division列中有这个数据:

BRONZE
SILVER
GOLD
DIAMOND

我把它Map到一个实体字段:

public enum Division {
    BRONZE,
    SILVER,
    GOLD,
    DIAMOND
}

@Entity
public class MyEntity {

  @Enumerated(EnumType.STRING)
  private Division division;

  ...
}

如果我使用默认排序,我会得到一个字母顺序:

  • [*] B & b Bungalow
    *DIAMOND
    *G
    *SILVER

但我想有矿石的质量排序(在枚举的顺序)。

3phpmpom

3phpmpom1#

排序(或排序)发生在数据库级别。所以不可能定义一个自定义的Comparator或类似的-如果这是你的意图。相反,数据库将需要知道 * 质量 * 以某种方式使用它作为顺序标准。

一个选项是按枚举的序号排序。这是唯一可能的,如果你把它存储在数据库中-而不是名称:

@Enumerated(EnumType.ORDINAL) // The default
private Division division;

第二个选项是将enum转换为Entity,并显式地将质量存储为新的整数字段。这样做的缺点是,你不能再使用常量值。
第三个选项Formula字段,具有显式的 name到quality Map(您也可以按公式字段排序):

@Enumerated(EnumType.STRING)
private Division division;

@Formula("case division when 'BRONZE' then 0 when 'SILVER' then 1 ... end")
private int divisionQuality;

这是最慢的选择-如果你的表中有很多行。

hc2pp10m

hc2pp10m2#

你可以做一个像这样的自定义查询,根据需要对枚举进行排序:

@Query("SELECT e FROM Entity e ORDER BY (CASE WHEN e.enumField = 'ENUM_VALUE' THEN 0 else 1 END)")
List<Entity> findAllInOrder();
6ovsh4lw

6ovsh4lw3#

我对枚举值使用如下顺序:

@Getter
public enum MyEnum {
   VAL1(1),
   VAL2(2),
   VAL3(3);

   private final int sortOrder;

   MyEnum(int sortOrder) {
       this.sortOrder = sortOrder;
   }
}

然后使用CriteriaBuilder.Case对结果进行排序:

CriteriaBuilder.Case<Integer> selectCase = cb.selectCase();
for (MyEnum value : MyEnum.values()) {
    selectCase.when(cb.equal(root.get(Object_.enumProperty), cb.literal(value)),
            value.getSortOrder());
}
selectCase.otherwise(4);
if (direction.isAscending()) {
    order = cb.asc(selectCase);
} else {
    order = cb.desc(selectCase);
}
query.orderBy(order);

相关问题