QueryDsl自定義返回對象
寫在前面
記錄在queryDsl使用過程中的一些實現,關於JPA集成queryDsl,以及自定義存儲庫的問題,這裏就不詳細介紹了,主要總結下QueryDsl的一些使用問題,可參考我上文總結,鏈接這裏
一、自定義返回對象
在我們集成queryDsl時,一般是這樣用的
@Override
public List<CityHotelVo> findcityHotel() {
JPAQuery<CityHotelVo> query = new JPAQuery<>(em);
QTCity c = QTCity.tCity;
QTHotel h = QTHotel.tHotel;
JPAQuery<Tuple> on = query.select(
c.id,
c.name,
h.name,
h.address).from(c).leftJoin(h).on(c.id.eq(h.city));
QueryResults<Tuple> rts = on.fetchResults();
List<Tuple> results = rts.getResults();
return results.stream().map(CityHotelVo::new).collect(Collectors.toList());
}
轉Vo實現
public CityHotelVo(Tuple t) {
this.id = t.get(QTCity.tCity.id);
this.cityName = t.get(QTCity.tCity.name);
this.hotelName = t.get(QTHotel.tHotel.name);
this.address = t.get(QTHotel.tHotel.address);
}
返回的是一個List,我們還需將tuple手動轉成我們自定義的VO對象,以下總結了可自動Tuple轉VO的幾種實現。
1.1、方式一
/**
* 方式一:使用Bean投影
* todo 這裏暫未調通
* @return
*/
@Override
public List<CityHotelVo> findcityHotel_2() {
JPAQuery<CityHotelVo> query = new JPAQuery<>(em);
QTCity c = QTCity.tCity;
QTHotel h = QTHotel.tHotel;
List<CityHotelVo> results1 = query.select(Projections.bean(CityHotelVo.class,
c.id.as("id"),
c.name.as("cityName"),
h.name.as("hotelName"),
h.address.as("address"))).from(c).leftJoin(h).on(c.id.eq(h.city)).fetchResults().getResults();
return results1;
}
1.2、方式二
/**
* 方式二 fields 投影
* todo 這裏暫未調通,全都爲null
* @return
*/
@Override
public List<CityHotelVo2> findcityHotel_3() {
JPAQuery<CityHotelVo> query = new JPAQuery<>(em);
QTCity c = QTCity.tCity;
QTHotel h = QTHotel.tHotel;
JPAQuery<CityHotelVo2> on = query.select(
Projections.bean(CityHotelVo2.class,
c.id,
c.name,
h.address))
.from(c).leftJoin(h).on(c.id.eq(h.city));
QueryResults<CityHotelVo2> cityHotelVo2QueryResults = on.fetchResults();
List<CityHotelVo2> results = cityHotelVo2QueryResults.getResults();
return results;
}
1.3、方式三
/**
* todo 成功測試
* 以上方法都是不能正常映射的
* 經測試,使用構造器方式可以映射
* @return
*/
@Override
public List<CityHotelVo2> findcityHotel_31() {
QTCity c = QTCity.tCity;
QTHotel h = QTHotel.tHotel;
JPAQueryFactory queryFactory = new JPAQueryFactory(em);
JPAQuery<CityHotelVo2> on = queryFactory.select(
Projections.constructor(CityHotelVo2.class,
c.id,
c.name,
h.address))
.from(c).leftJoin(h).on(c.id.eq(h.city));
List<CityHotelVo2> results = on.fetchResults().getResults();
return results;
}
1.4、總結,這裏只是幾種嘗試,可供參考,可能和QueryDsl版本依賴有關,我本地就測通了方式三,當前版本信息
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<springboot.start.version>2.0.8</springboot.start.version>
<queryDsl>4.1.4</queryDsl>
<queryslBuild>1.1.3</queryslBuild>
</properties>