【问题标题】:select query in postgresql with jsonb column is not working in jpa在带有 jsonb 列的 postgresql 中选择查询在 jpa 中不起作用
【发布时间】:2018-03-07 08:17:26
【问题描述】:

我的 postgres 表中有一个 jsonb 列。我正在使用的选择查询是

SELECT distinct metadata->'Country' as metadata FROM documents WHERE metadata?'Country' order by metadata->'Country' asc

它在 postgresql 中运行良好。元数据列中的数据就像

'{"Country":"US","Vendor":"ABC","Year":"2011"}'

选择查询的输出是'US'

当我在 jpa 中使用此查询时,“?”有问题在选择查询中使用,因为它需要一个参数。

Query query = this.em.createNativeQuery(
            "SELECT distinct cast(metadata->"+title+") as metadata FROM documents WHERE metadata?"+title+" order by metadata->"+title+" "+sort);
    List<Object> obj=query.getResultList(); 

我该如何解决这个问题?

【问题讨论】:

  • 您不能使用准备好的语句占位符来配置查询的结构。只传递值。所以你可以使用where foo.bar = :someValue,但不能使用where foo.:someProp = 2
  • @JBNizet 我删除了所有参数并内联。但 '?'仍然是一个问题。预期位置参数计数:1,实际参数:[]
  • 我认为 jpa 不理解 ? 运算符 - 你可以用我猜的函数解决它
  • @VaoTsun 函数?可以举个例子吗?
  • 在下面给出一个答案 - 您可以通过明确检查其值是否不为空来检查顶级键是否存在

标签: java sql postgresql jpa jdbc


【解决方案1】:

我假设 jpa 不理解 ? 运算符 - 您可以尝试使用类似 metadata-&gt;'Country' is not null 的方法来解决它?例如:

t=# with j(b) as (values('{"a":0}'::jsonb))
t-# select b from j
t-# where b ? 'a';
    b
----------
 {"a": 0}
(1 row)

t=# with j(b) as (values('{"a":0}'::jsonb))
t-# select b from j
t-# where b->'a' is not null;
    b
----------
 {"a": 0}
(1 row)

t=# with j(b) as (values('{"a":0}'::jsonb))
t-# select b from j
t-# where b->'not exising' is not null;
 b
---
(0 rows)

更新

基于 cmets 和您的查询:

Query query = this.em.createNativeQuery(
            "SELECT distinct cast(metadata->"+title+") as metadata FROM documents WHERE metadata ?? "+title+" order by metadata->"+title+" "+sort);
    List<Object> obj=query.getResultList();

使用转义和另一个:

Query query = this.em.createNativeQuery(
            "SELECT distinct cast(metadata->"+title+") as metadata FROM documents WHERE metadata->'"+title+"' is not null order by metadata->"+title+" "+sort);
    List<Object> obj=query.getResultList();

为了避免? 运算符,只需检查-&gt; 运算符是否存在密钥

【讨论】:

  • 我不明白你的意思。 '::' 也显示相同的问题。你能用我的查询解释一下吗?TIA
【解决方案2】:

通过在 postgres 中创建函数解决了这个问题

CREATE OR REPLACE FUNCTION public.get_metadata(
var1 text,
sort text)
RETURNS TABLE(fldvalue text) 
LANGUAGE 'plpgsql'
COST 100
VOLATILE 
ROWS 1000
AS $BODY$

 BEGIN

  IF(sort='asc') THEN
  RETURN QUERY SELECT distinct metadata->>var1 as fldvalue FROM documents WHERE metadata?var1 order by fldvalue asc;
  ELSE 
  RETURN QUERY SELECT distinct metadata->>var1 as fldvalue FROM documents WHERE metadata?var1 order by fldvalue desc;
  END IF;
END

$BODY$;

【讨论】:

    猜你喜欢
    • 2022-01-18
    • 1970-01-01
    • 2022-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-12
    • 1970-01-01
    • 2020-04-19
    相关资源
    最近更新 更多