Spring Data JPA JSONB参数化
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring Data JPA JSONB参数化相关的知识,希望对你有一定的参考价值。
将此查询转换为Spring Data Repository nativeQuery
的正确语法(JPA,Spring Data或SpEL)是什么?
SELECT *
FROM mytable
WHERE f_jsonb_arr_lower(myjsonb -> 'myArray', 'subItem', 'email')
@> '"foo@foo.com"';
我想使用输入参数而不是硬编码"foo@foo.com"
。
我的模型:Postgres myTable
,带有JSONB列myJsonb
:
{
"myArray": [
{
"subItem": {
"email": "bar@bar.com"
}
},
{
"subItem": {
"email": "foo@foo.com"
}
}
]
}
索引描述了here。
硬编码版本有效:
@Query(value =
"SELECT m.* " +
" FROM mytable AS m " +
" WHERE f_jsonb_arr_lower(myjsonb -> 'myArray' ,'subItem', 'email') " +
" @> '"foo@foo.com"' " +
" ORDER BY ?#{#pageable} ",
// Spring Data nativeQueries with Pageable require a separate countQuery:
countQuery =
"SELECT count(m.id) " +
" FROM mytable AS m " +
" WHERE f_jsonb_arr_lower(myjsonb -> 'myArray' ,'subItem', 'email') " +
" @> '"foo@foo.com"' ",
nativeQuery = true)
Page<MyTableEntity> findAllHardcodedPageable(Pageable pageable);
但是尝试在Spring Data存储库中利用lowercaseEmailAddress
参数nativeQuery不起作用:
@Query(value =
"SELECT m.* " +
" FROM mytable AS m " +
" WHERE f_jsonb_arr_lower(myjsonb -> 'myArray' ,'subItem', 'email') " +
" @> '"?{lowercaseEmailAddress}"' " +
" ORDER BY ?#{#pageable} ",
countQuery =
"SELECT count(m.id) " +
" FROM mytable AS m " +
" WHERE f_jsonb_arr_lower(myjsonb -> 'myArray' ,'subItem', 'email') " +
" @> '"?{lowercaseEmailAddress}"' ",
nativeQuery = true)
Page<MyTableEntity> findAllByEmailPageable
(String lowercaseEmailAddress, Pageable pageable);
在我的Postgres查询日志记录中,我可以看到从未设置lowercaseEmailAddress
参数:
LOG: execute S_2: COMMIT
LOG: execute S_3: BEGIN
LOG: execute <unnamed>: SELECT count(m.id) FROM mytable
AS m WHERE f_jsonb_arr_lower(myjsonb -> 'myArray',
'subitem', 'email') @> '"?1"'
LOG: execute S_11: ROLLBACK
答案
找到答案:
1)只将双引号的String
传递给spring数据存储库方法:
String emailAddressWithDoubleQuotes = String.format(""%s"",emailAddress);
result = repository.findAllByEmailPageable(emailAddressWithDoubleQuotes, pageRequest).getContent();
2)Spring Repository @Query
需要在括号中包含SpEL表达式并将其转换为jsonb
:
static final String FIND_ALL_BY_EMAIL_QUERY = " FROM mytable AS m " +
" WHERE f_jsonb_arr_lower(metadata -> 'myArray', 'subItem', 'email') " +
" @> ( ?#{#lowercaseEmailAddress} )\:\:jsonb";
@Query( // only use 'ORDER BY #pageableWithNativeSort' on 'value' query:
value = "SELECT m.* " + FIND_ALL_BY_EMAIL_QUERY + " ORDER BY ?#{#pageableWithNativeSort} ",
// Spring Data nativeQueries with Pageable require a separate 'countQuery':
countQuery = "SELECT count(m.id) " + FIND_ALL_BY_EMAIL_QUERY,
nativeQuery = true)
Page<OrderEntity> findAllBysubItemEmail(
@Param("lowercaseEmailAddress") String lowercaseEmailAddress,
@Param("pageableWithNativeSort") Pageable pageableWithNativeSort);
以上是关于Spring Data JPA JSONB参数化的主要内容,如果未能解决你的问题,请参考以下文章
如何在 jsonb 列上使用 Spring JPA 进行查询?
使用带有 Spring Data 和绑定参数的 Postgres JSONB 查询失败并出现 InvalidDataAccessApiUsageException