Jos*_* C. 4 postgresql spring jpa spring-data-jpa
我在使用postgres 9.4实例获取此本机查询时遇到问题.
我的存储库有一个方法:
@Query(value = "SELECT t.* " +
"FROM my_table t " +
"WHERE t.field_1 = ?1 " +
"AND t.field_2 = 1 " +
"AND t.field_3 IN ?2 " +
"AND t.jsonb_field #>> '{key,subkey}' = ?3",
nativeQuery = true)
List<Entity> getEntities(String field1Value,
Collection<Integer> field3Values,
String jsonbFieldValue);
Run Code Online (Sandbox Code Playgroud)
但是日志显示了这个:
SELECT t.* FROM my_table t
WHERE t.field_1 = ?1
AND t.field_2 = 1
AND t.field_3 IN ?2
AND t.jsonb_field ? '{key,subkey}' = ?3
Run Code Online (Sandbox Code Playgroud)
我得到这个例外:
内部异常:org.postgresql.util.PSQLException:没有为参数2指定值.
我在方法调用之前直接记录了参数,并且它们都是提供的.
我不确定为什么在日志中#>>显示?.我需要逃脱#>>吗?我需要格式化集合IN吗?我需要逃离json路径吗?
当我直接对db执行查询时,它可以工作.例:
SELECT *
FROM my_table t
WHERE t.field_1 = 'xxxx'
AND t.field_2 = 1
AND t.field_3 IN (13)
AND t.jsonb_field #>> '{key,subkey}' = 'value'
Run Code Online (Sandbox Code Playgroud)
Geo*_*lou 12
我发现弹簧数据中的规范 api 非常有用.
假设我们有一个名称实体和名称类型为JSON(B)Product的属性title.
我假设此属性包含不同语言的产品标题.一个例子可能是:{"EN":"Multicolor LED light", "EL":"????????? LED ???"}.
下面的源代码通过标题和作为参数传递的语言环境找到(或者更多,如果它不是唯一字段)产品.
@Repository
public interface ProductRepository extends JpaRepository<Product, Integer>, JpaSpecificationExecutor<Product> {
}
public class ProductSpecification implements Specification<Product> {
private String locale;
private String titleToSearch;
public ProductSpecification(String locale, String titleToSearch) {
this.locale = locale;
this.titleToSearch = titleToSearch;
}
@Override
public Predicate toPredicate(Root<Product> root, CriteriaQuery<?> query, CriteriaBuilder builder) {
return builder.equal(builder.function("jsonb_extract_path_text", String.class, root.<String>get("title"), builder.literal(this.locale)), this.titleToSearch);
}
}
@Service
public class ProductService {
@Autowired
private ProductRepository productRepository;
public List<Product> findByTitle(String locale, String titleToSearch) {
ProductSpecification cs = new ProductSpecification(locale, titleToSearch);
return productRepository.find(cs);
// Or using lambda expression - without the need of ProductSpecification class.
// return productRepository.find((Root<ProductCategory> root, CriteriaQuery<?> query, CriteriaBuilder builder) -> {
// return builder.equal(builder.function("jsonb_extract_path_text", String.class, root.<String>get("title"), builder.literal(locale)), titleToSearch);
// });
}
}
Run Code Online (Sandbox Code Playgroud)
您可以在此处找到有关应如何使用Spring Data的其他答案.
希望有所帮助.
您还可以使用FUNCJPQL 关键字来调用自定义函数,而不使用本机查询。
像这样的事情,
@Query(value = "SELECT t FROM my_table t "
+ "WHERE t.field_1=:field_1 AND t.field_2=1 AND t.field_3 IN :field_3 "
+ "AND FUNC('jsonb_extract_path_text', 'key', 'subkey')=:value")
List<Entity> getEntities(@Param("field_1") String field_1, @Param("field_3") Collection<Integer> field_3, @Param("value") String value);
Run Code Online (Sandbox Code Playgroud)
如果由于某种原因运算符被转换为问号,那么您应该尝试使用该函数。\doS+ #>>您可以在psql控制台中使用找到相应的函数。它告诉我们调用的函数是jsonb_extract_path_text。这将使您的查询:
@Query(value = "SELECT t.* " +
"FROM my_table t " +
"WHERE t.field_1 = ?1 " +
"AND t.field_2 = 1 " +
"AND t.field_3 IN ?2 " +
"AND jsonb_extract_path_text(t.jsonb_field, '{key,subkey}') = ?3",
nativeQuery = true)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
13862 次 |
| 最近记录: |