【问题标题】:JPA domain.Sort based on content of json column?JPA domain.Sort基于json列的内容?
【发布时间】:2022-01-14 18:37:11
【问题描述】:

我有一列定义如下:

@Type(type = "json")
@Column(name = "ex_data")
@JsonProperty
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS)
private T exData;

如果给定类型 T,我可以在表中存储各种基本 JSON 对象,如下所示:

{
  "active": true,
  "color": "red",
  "flavor": "cherry"
}

如果我想针对表创建一个排序、分页的查询,是否可以将 JSON 的内容用于 Sort 对象?

即与此等效,目前不起作用:

 Sort sort = Sort.by("exData.color").ascending();

【问题讨论】:

  • 作为答案的一部分提供的选项之一是否有助于解决您的问题?

标签: mysql json sorting jpa


【解决方案1】:

JPA 不直接支持 JSON。

一种方法是使用原生 SQL 函数来访问嵌套在 json 列中的特定属性。

很遗憾,使用 Sort 时不支持原生表达式,它只接受实体属性来排序。


方案一:原生查询带json键参数和分页

@Repository
public interface JsonSortNativeRepositoryMySql extends JpaRepository<JsonSortNativeEntity, Long> {

    @Query(value = "SELECT * FROM json_sort_native_entity ORDER BY "
                    // flexibly extract the sort value from json:
                    + "my_json_column->> :sortKey" //
                    + " DESC", //
                    countQuery = "select count(*) from json_sort_native_entity", //
                    nativeQuery = true)
    Page<JsonSortNativeEntity> findSortedNative(Pageable pageable, @Param("sortKey") String sortKey);
}

不带Sort参数创建对应的pageable,调用原生查询方法时可以动态提供排序键:

var pageable = PageRequest.of(0, 20); // first page with 20 entries
var pageResult = repository.findSortedNative(pageable, "$.color");

解决方案 2sort by computed attribute value

另一个选项是使用 Hibernate @Formula 作为Entity 的一部分来指定计算属性值:

@Formula("my_json_column->>'$.color'") // <-- fixed key "color" to extract from json column
private String formulaValue;

这样,一个普通的Sort就可以使用了:

var pageable = PageRequest.of(0, 20, Sort.by("formulaValue").descending());
var pageResult = repository.findAll(pageable); // standard JpaRepository method

但是,在这种情况下,提取排序值的键是固定的(可能的替代方案:Spring Data - Page Request - order by function

MySQL JSON 参考:https://dev.mysql.com/doc/refman/8.0/en/json.html

【讨论】:

    猜你喜欢
    • 2017-02-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多