2017-10-16 62 views
0

我有一個查詢,有更多的列,那麼我的實體類有。如何映射從本地查詢得到的結果在休眠?

爲了不讓休眠投訴,我一定要註釋添加到字段像

@Transient 
private Integer count; 

但是這樣做,這使得休眠無法映射計數。假設我的查詢是

session.createSQLQuery("SELECT p.*, count(p.id), sqrt(1+2) as distance FROM post p group by p.id") 

我知道查詢沒有任何邏輯意義。這只是例如。從上面的查詢返回的列將包含所有內容和兩個額外的列,數量和距離。我想將結果映射到我的entity,計數和距離用@Transient註釋,或者如果有更好的方法來映射結果。我非常樂意這樣做。目標不是在一個實體中這樣做,而是在映射結果中使用class。我試過撥打addEntity(),但似乎沒有幫助。

+0

你真的需要一個實體的結果呢?意思是你想改變你從這個查詢中得到的數據嗎? –

+0

不,這就是爲什麼我說目標是讓班級不是實體。我只是因爲碰巧找到一個使用實體來實現這一點的帖子,而這是我嘗試的最後一件事 – user1865027

回答

1

您可以使用Result Set Transformer來實現這一點。

步驟1)創建的所有領域一個新的DTO類,您的查詢將返回

步驟2)添加下面一行

setResultTransformer(Transformers.aliasToBean(DTO.class)) 

例子:

List resultWithAliasedBean = session.createQuery(
    "SELECT p.*, count(p.id), sqrt(1+2) as distance FROM post p group by p.id") 
    .setResultTransformer(Transformers.aliasToBean(DTO.class)) 
    .list(); 

DTO dto = (DTO) resultWithAliasedBean.get(0); 

注:確保DTO類中的字段名稱與查詢返回的列名相匹配。

0

我看到你正在使用Hibernate所以Yathish的答案工作正常。

但是,如果你想與JPA規範做到這一點,那麼你可以使用結果集映射

Query q = em.createNativeQuery(
    "SELECT c.id, c.name, COUNT(o) as orderCount, AVG(o.price) AS avgOrder " + 
    "FROM Customer c " + 
    "JOIN Orders o ON o.cid = c.id " + 
    "GROUP BY c.id, c.name", 
    "CustomerDetailsResult"); 

@SqlResultSetMapping(name="CustomerDetailsResult", 
    classes={ 
     @ConstructorResult(targetClass=com.acme.CustomerDetails.class, 
      columns={ 
       @ColumnResult(name="id"), 
       @ColumnResult(name="name"), 
       @ColumnResult(name="orderCount"), 
       @ColumnResult(name="avgOrder", type=Double.class)}) 
    }) 

有你有從設置到DTO SQL結果specifiy列的mappin。

如果您認爲這很複雜,有一個名爲QLRM(查詢語言結果映射器)的開源項目將任何SQL語句映射到POJO。

http://simasch.github.io/qlrm/

最後但並非最不重要的,如果你會做大量的SQL處理,爲什麼不看看jOOQ:https://www.jooq.org/