2017-09-26 80 views
1

我的postgres表中有一個jsonb列。我正在使用的選擇查詢是在postgresql中使用jsonb列選擇查詢不在jpa中工作

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

它從postgresql正常工作。在元數據colummn數據就像是選擇查詢的

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

輸出爲「美國」

當我使用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(); 

我該如何解決這個問題?

+0

不能使用準備好的語句佔位符配置查詢的結構功能解決了這個問題。只傳遞值。所以你可以使用'where foo.bar =:someValue',而不是'where foo.:someProp = 2'。 –

+0

@JBNizet我刪除了所有參數並內聯給出。但'?'仍然是一個問題。預期的位置參數計數:1,實際參數:[] –

+0

我假設jpa不包含'?'運算符 - 你可以用函數來解決它我猜 –

回答

0

通過創建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$; 
0

我假設jpa不理解?運算符 - 您可以嘗試使用類似於metadata->'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) 

更新

根據意見和您的查詢:

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(); 

避免?運營商,只是檢查是與存在關鍵運營商

+0

我不明白你的意思。'::'也顯示相同的問題。你能解釋我的查詢嗎? –