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");
解决方案 2:sort 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