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出來(lái)的自定義對(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注入問(wèn)題,例如:param傳入Running' or 1=1 --\t 上述查詢會(huì)將查詢整個(gè)數(shù)據(jù)表。解決方法如下,使用預(yù)編譯防止sql注入問(wèn)題。
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的寫(xiě)法,排查問(wèn)題的時(shí)候看得頭疼(別問(wèn),問(wèn)就是被坑過(guò)/捂臉.jpg/)。所以方法二即便可行,我私心還是不想推薦。
方法三、Dao層使用Map接收自定義對(duì)象
使用List<Map> 接收返回結(jié)果,無(wú)論是原生sql還是hql都支持,當(dāng)然也支持分頁(yè),只需要把返回對(duì)象改為Page<Map>即可,其他操作與普通分頁(yè)沒(méi)有差別。
@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操作起來(lái)挺麻煩的。可以用如下解決方案,先用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ì)有問(wèn)題,數(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)文章
使用JVMTI實(shí)現(xiàn)SpringBoot的jar加密,防止反編譯
這篇文章主要介紹了使用JVMTI實(shí)現(xiàn)SpringBoot的jar加密,防止反編譯問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-08-08
java使用FFmpeg合成視頻和音頻并獲取視頻中的音頻等操作(實(shí)例代碼詳解)
這篇文章主要介紹了java使用FFmpeg合成視頻和音頻并獲取視頻中的音頻等操作,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-02-02
springboot自動(dòng)重啟的簡(jiǎn)單方法
Springboot提供了熱部署的方式,當(dāng)發(fā)現(xiàn)任何類發(fā)生了改變,馬上通過(guò)JVM類加載的方式,加載最新的類到虛擬機(jī)中。這篇文章主要介紹了springboot自動(dòng)重啟的實(shí)現(xiàn)方法,需要的朋友可以參考下2018-04-04
Java實(shí)現(xiàn)瀏覽器大文件上傳的示例詳解
文件上傳是許多項(xiàng)目都有的功能,用戶上傳小文件速度一般都很快,但如果是大文件幾個(gè)g,幾十個(gè)g的時(shí)候,上傳了半天,馬上就要完成的時(shí)候,網(wǎng)絡(luò)波動(dòng)一下,文件又要重新上傳,所以本文給大家介紹了Java實(shí)現(xiàn)瀏覽器大文件上傳的示例,需要的朋友可以參考下2024-07-07
Java中sleep()與wait()的區(qū)別總結(jié)
因?yàn)樽罱鼘W(xué)習(xí)時(shí)正好碰到這兩個(gè)方法,就查閱相關(guān)資料,并通過(guò)程序?qū)崿F(xiàn),進(jìn)行區(qū)別總結(jié)一下,所以下面這篇文章主要給大家總結(jié)介紹了關(guān)于Java中sleep()與wait()區(qū)別的相關(guān)資料,需要的朋友可以參考,下面來(lái)一起看看吧。2017-05-05
一文搞懂Spring中@Autowired和@Resource的區(qū)別
@Autowired?和?@Resource?都是?Spring/Spring?Boot?項(xiàng)目中,用來(lái)進(jìn)行依賴注入的注解。它們都提供了將依賴對(duì)象注入到當(dāng)前對(duì)象的功能,但二者卻有眾多不同,并且這也是常見(jiàn)的面試題之一,所以我們今天就來(lái)盤(pán)它2022-08-08
Java操作Elasticsearch?rest-high-level-client?的基本使用
這篇文章主要介紹了Java操作Elasticsearch?rest-high-level-client?的基本使用,本篇主要講解一下?rest-high-level-client?去操作?Elasticsearch的方法,結(jié)合實(shí)例代碼給大家詳細(xì)講解,需要的朋友可以參考下2022-10-10

