我在使用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);
但是日志显示了这个:
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
我得到了这个例外:
内部异常: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'
答案 0 :(得分:6)
我发现春季数据中的Specification api非常有帮助
假设我们有一个名为\\item $Dom\\left(Q\\right)\\ne {\\rm R}^{2} $ y uno de los puntos no pertenecientes al dominio es $\\left({1\\over 2} ,{1\\over 2} \right).$
的实体和一个名为Product
的JSON(B)类型的属性。
我假设此属性包含不同语言的产品标题。一个例子可能是:title
下面的源代码通过标题和作为参数传递的语言环境找到(或者更多,如果它不是唯一字段)产品。
{"EN":"Multicolor LED light", "GR":"Πολύχρωμο LED φώς"}
您可以找到有关使用Spring Data here的方式的另一个答案 希望有所帮助。
答案 1 :(得分:2)
也许这是一个古老的话题,但是我在这里使用spring规范按字段在jsonb中进行搜索。
如果要搜索“ LIKE”,则需要使用以下代码创建类似的析取物:
final Predicate likeSearch = cb.disjunction();
此后,假设您的对象中有一个jsonb字段,即address,而address有5个字段。要在所有这些字段中进行搜索,您需要为所有字段添加“ LIKE”表达式:
for (String field : ADDRESS_SEARCH_FIELDS) {
likeSearch.getExpressions().add(cb.like(cb.lower(cb.function("json_extract_path_text", String.class,
root.get("address"), cb.literal(field))), %searchKey%));
}
其中cb是相同的criteriaBuilder。 %searchKey%是您要在地址字段中搜索的内容。
希望这会有所帮助。
答案 2 :(得分:1)
如果由于某种原因将操作员转换为问号,则应尝试使用该功能。您可以在psql控制台中使用\doS+ #>>
找到相应的函数。它告诉我们所谓的函数是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)
答案 3 :(得分:1)
我建议不要遵循这种方式,我不喜欢遵循通用的CRUD方式(也使用StrongLoop Loopback方式的高级自动生成的DAO方法,对于Spring Data Rest maven插件,但它目前只是实验性的)。 但是使用这个JSON,现在该做什么...我正在通过@Document注释寻找类似于Spring Data中的MongoDB JSON处理的东西,但是这还没有。但还有其他方法: - )
一般来说,它是关于实现您的JSON用户类型(UserType接口):
public class YourJSONBType implements UserType {
最后,您需要使用已实现的用户类型的规范来增强JPA类:
@Entity
@Data
@AllArgsConstructor
@NoArgsConstructor
@TypeDef(name = "JsonbType", typeClass = YourJSONBType.class)
public class Person {
@Id
@GeneratedValue
private Long id;
@Column(columnDefinition = "jsonb")
@Type(type = "JsonbType")
private Map<String,Object> info;
}
在这里查看另一篇相关文章: Mapping postgreSQL JSON column to Hibernate value type
完整的实施示例如下:
类似,但这里有一些不同的例子: http://www.wisely.top/2017/06/27/spring-data-jpa-postgresql-jsonb/?d=1
答案 4 :(得分:0)
您还可以使用FUCT
JPQL键来调用自定义函数,而不使用本机查询
像这样的东西,
@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);