Spring?Data?Jpa返回自定義對(duì)象的3種方法實(shí)例
tasks表對(duì)應(yīng)的Entity
@Entity @NoArgsConstructor @AllArgsConstructor @Table(name = "tasks") @Data public class Tasks extends BaseEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private int taskId; private Integer websiteId; private String status; private String lastOperator; private String lastOperationTime; private String jobId; private int retryTimes; }
websites表對(duì)應(yīng)的Entity
@Entity @Table(name = "websites") @Data @NoArgsConstructor @AllArgsConstructor public class Websites extends BaseEntity{ @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private int websiteId; private String country; private String websiteName; private String baseUrl; private String smartphoneUrl; private String tabletUrl; private String smartdeviceUrl; private String websiteCategory; private String webtypeRefreshRate; private String urlRefreshRate; private String configTime; private String configDesc; }
自定義對(duì)象
@Data @NoArgsConstructor @AllArgsConstructor public class CustomizedDto implements Serializable { private static final long serialVersionUID = -7242005560621561106L; private String country; private String websiteName; private String baseUrl; private String status; }
方法一、簡(jiǎn)單查詢直接new對(duì)象
使用hql,將結(jié)果返回到new出來的自定義對(duì)象中,注意,自定義對(duì)象中要有對(duì)應(yīng)的構(gòu)造函數(shù)。
@Query(value = "select new com.bigdata.mrcrawler.dto.CustomizedDto(w.country,w.websiteName,w.baseUrl,t.status) " + "from Websites w join Tasks t on w.id=t.websiteId " + "where t.status=?1") List<CustomizedDto> getByStatus1(String status);
但是這個(gè)方法只使用于簡(jiǎn)單的查詢語(yǔ)句,如果遇到復(fù)雜查詢需要使用原生SQL(即nativeQuery=true)時(shí), 此方法不適用,會(huì)拋出如下異常。
@Query(value = "select w.country as country,w.website_name as websiteName,w.base_url as baseUrl,t.status as status " + "from websites w join tasks t on w.website_id=t.website_id " + "where t.status=?1",nativeQuery = true) List<CustomizedDto> getByStatus2(String status);
No converter found capable of converting from type [org.springframework.data.jpa.repository.query.AbstractJpaQuery$TupleConverter$TupleBackedMap] to type [com.bigdata.mrcrawler.dto.CustomizedDto]
方法二、Service層使用EntityManager
直接在Service層使用EntityManager進(jìn)行查詢,可以自由組裝各種復(fù)雜sql。
public List<CustomizedDto> t(String param) { String sql = "select w.country as country,w.website_name as websiteName,w.base_url as baseUrl,t.status as status " + "from websites w join tasks t on w.website_id=t.website_id " + "where t.status='" + param + "'"; List<CustomizedDto> res = entityManager.createNativeQuery(sql).getResultList(); return res; }
但是會(huì)有sql注入問題,例如:param傳入Running' or 1=1 --\t 上述查詢會(huì)將查詢整個(gè)數(shù)據(jù)表。解決方法如下,使用預(yù)編譯防止sql注入問題。
public List<CustomizedDto> t(String param) { String sql = "select w.country as country,w.website_name as websiteName,w.base_url as baseUrl,t.status as status " + "from websites w join tasks t on w.website_id=t.website_id " + "where t.status=:param" ; Query nativeQuery = entityManager.createNativeQuery(sql); nativeQuery.setParameter("param", param); List<CustomizedDto> res = nativeQuery.getResultList(); return res; }
然而,個(gè)人很不喜歡這種代碼中嵌入大片大片sql的寫法,排查問題的時(shí)候看得頭疼(別問,問就是被坑過/捂臉.jpg/)。所以方法二即便可行,我私心還是不想推薦。
方法三、Dao層使用Map接收自定義對(duì)象
使用List<Map> 接收返回結(jié)果,無論是原生sql還是hql都支持,當(dāng)然也支持分頁(yè),只需要把返回對(duì)象改為Page<Map>即可,其他操作與普通分頁(yè)沒有差別。
@Query(value = "select w.country as country,w.website_name as websiteName,w.base_url as baseUrl,t.status as status " + "from websites w join tasks t on w.website_id=t.website_id " + "where t.status=?1",nativeQuery = true) List<Map> getByStatus3(String status);
Service層也需要用List<Map>進(jìn)行接收。
public List<Map> t(String param) { return testRepository.getByStatus3(param); }
如果后續(xù)還有其他操作,還是需要轉(zhuǎn)成自定義對(duì)象怎么辦,畢竟Map操作起來挺麻煩的??梢杂萌缦陆鉀Q方案,先用Object進(jìn)行接收,然后強(qiáng)轉(zhuǎn)成自定義對(duì)象List。
public List<CustomizedDto> t(String param) { Object data = testRepository.getByStatus3(param); return (List<CustomizedDto>)data; }
強(qiáng)轉(zhuǎn)需要注意自定義對(duì)象和數(shù)據(jù)庫(kù)中字段類型的強(qiáng)一致性,如數(shù)據(jù)庫(kù)中datetime類型,自定義對(duì)象對(duì)應(yīng)的字段必須是Date,不能是String,否則轉(zhuǎn)換的時(shí)候會(huì)有問題,數(shù)據(jù)會(huì)丟失。
總結(jié)
到此這篇關(guān)于Spring Data Jpa返回自定義對(duì)象的3種方法的文章就介紹到這了,更多相關(guān)Spring Data Jpa返回自定義對(duì)象內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
基于java實(shí)現(xiàn)簡(jiǎn)單的銀行管理系統(tǒng)
這篇文章主要介紹了基于java實(shí)現(xiàn)簡(jiǎn)單的銀行管理系統(tǒng),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-01-01教你利用springboot集成swagger并生成接口文檔
有很多小伙伴不會(huì)利用springboot集成swagger并生成接口文檔,今天特地整理了這篇文章,文中有非常詳細(xì)的代碼圖文介紹及代碼示例,對(duì)不會(huì)這個(gè)方法的小伙伴們很有幫助,需要的朋友可以參考下2021-05-05Java動(dòng)態(tài)代理實(shí)現(xiàn)_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
動(dòng)態(tài)代理作為代理模式的一種擴(kuò)展形式,廣泛應(yīng)用于框架(尤其是基于AOP的框架)的設(shè)計(jì)與開發(fā),本文將通過實(shí)例來講解Java動(dòng)態(tài)代理的實(shí)現(xiàn)過程2017-08-08超細(xì)講解Java調(diào)用python文件的幾種方式
有時(shí)候我們?cè)趯慾ava的時(shí)候需要調(diào)用python文件,下面這篇文章主要給大家介紹了關(guān)于Java調(diào)用python文件的幾種方式,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-12-12Java使用TCP實(shí)現(xiàn)在線聊天的示例代碼
這篇文章主要介紹了Java使用TCP實(shí)現(xiàn)在線聊天的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-01-01Java實(shí)現(xiàn)AC自動(dòng)機(jī)全文檢索示例
本篇文章主要介紹了Java實(shí)現(xiàn)AC自動(dòng)機(jī)全文檢索示例,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-02-02