Springboot?JPA如何使用distinct返回對象
JPA如何使用distinct返回對象
package com.frank.jpaBatchSave.repository;
import com.frank.jpaBatchSave.entity.Person;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface PersonRepository extends PagingAndSortingRepository<Person, Integer> {
@Query("select distinct new Person(p.name, p.province, p.city) from Person p")
List<Person> getAllPerson();
}這里如果需要返回的是對象,則需要new Person(p.name, p.province, p.city),同時Person類必須要有三參的構(gòu)造器。
public Person(String name, String province, String city) {
? ? ? ? this.name = name;
? ? ? ? this.province = province;
? ? ? ? this.city = city;
? ? }因為:select distinct name, province, city) from Person p 這樣寫的話返回的是Object[]數(shù)組。所以需要使用上面的方式。
JPA自定義返回對象
任何ORM框架都少不了開放自定義sql的問題。jpa自然也不例外,很多場景需要寫復(fù)雜sql的。
首先定義一個方法簽名,然后打上@Query注解。像下面這樣,需要注意nativeQuery,這個表示query中的字符以原始的sql語句執(zhí)行,也就是不做任何調(diào)整。你寫啥,就執(zhí)行啥sql語句。但是想返回自定義的實體,Sorry,做不到。的用另一種方式。
@Query(value = "SELECT * from table where id= :id", nativeQuery = true)
List<aa> getByaaId(@Param("id") BigInteger id);方法一
下面這個就是實現(xiàn)自定義的實體方法。首先需要定義個實體,這個實體必須包含無參和全參構(gòu)造函數(shù)。然后去掉nativeQuery,同時還有一點必須注意,寫的語句里面不是數(shù)據(jù)庫中對應(yīng)的實際表名,而是你定義的實體映射。比如下面的table1和table2,其實都是你定義的實體類的名字,不是你的數(shù)據(jù)庫表名,是你代碼中映射數(shù)據(jù)表的實體類名。
@Data
@NoArgsConstructor
@AllArgsConstructor
public class aaDto {
? ? private String aa;
? ? private String bb;
? ? private String cc;
}
@Query(value = "SELECT new com.xxx.xxx.dto.aaDto(i.aa,i.bb,i.cc) FROM table1 i JOIN table2 e on i.id=e.id")
List<aaDto> getList();方法二
方法一這種寫法還是非常不靈活,有時候?qū)懸恍┖瘮?shù)什么的,估計會搞死,還是得寫原生的sql才行。我說的查詢字段屬于多個表。如果只查詢一個表字段,關(guān)聯(lián)查詢只是條件,可以直接返回對應(yīng)的實體也是沒問題的。
List<Map<String, Object>> @Query(value = "SELECT a.aa,b.bb from a LEFT JOIN b a.id=b.id", nativeQuery = true) List<Map<String, String>> getFundAccountList();
這樣返回的數(shù)據(jù)就是一個集合,是鍵值型的,如果我們實在想用對象,不用Map,我是先把返回參數(shù)序列化成json,然后將這個json再反序列化成我們想要的對象即可。
方法三
在繼承jpa接口的時候,里面的實體類寫你的對應(yīng)結(jié)果類,就可以用相應(yīng)的結(jié)果來接收了。
public interface xxxDTORepository extends JpaRepository<xxxDTO, Long>
方法四
以上的方法都是基于繼承JpaRepository接口來實現(xiàn),其實又另外一種更加靈活的方式,這種方式可以更加靈活的寫sql和定義返回對象。
@PersistenceContext private EntityManager entityManager;
記錄一個錯誤:Path expected for join!
Caused by: org.hibernate.hql.internal.ast.QuerySyntaxException: Path expected for join!
就這么個錯誤,其實很簡單,只是我沒有細(xì)看錯誤信息,導(dǎo)致在正確的語句找錯誤,找不到。出現(xiàn)這個錯誤,后面會跟你寫的hql語句,注意留意這個hql語句,仔細(xì)檢查,他一定是有錯誤的。

有個博客說需要添加映射關(guān)系,其實完全不用的,就是一對多,A類里面包含List<B> 是不需要這樣的,獨立類沒任何關(guān)聯(lián)也是可以的,細(xì)心細(xì)心細(xì)心。。。
順帶再來記錄一個問題吧,這個問題簡單,出現(xiàn)下面這段代碼,后面會跟一些信息,根據(jù)信息就可以知道是返回對象的構(gòu)造函數(shù)類型問題,既然這樣,那就調(diào)整下返回實體對象的屬性類型即可。
Caused by: org.hibernate.hql.internal.ast.QuerySyntaxException: Unable to locate appropriate constructor on class
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
新的Java訪問mysql數(shù)據(jù)庫工具類的操作代碼
本文通過實例代碼給大家介紹新的Java訪問mysql數(shù)據(jù)庫工具類的方法,本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧2021-12-12
教你用MAT工具分析Java堆內(nèi)存泄漏問題的解決方法
今天給大家?guī)淼氖顷P(guān)于Java的相關(guān)知識,文章圍繞著如何使用MAT工具分析Java堆內(nèi)存泄漏問題的解決方法展開,文中有非常詳細(xì)的介紹及代碼示例,需要的朋友可以參考下2021-06-06
mybatis入門_動力節(jié)點Java學(xué)院整理
這篇文章主要為大家詳細(xì)介紹了mybatis入門的相關(guān)資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-09-09

