Spring?Data?JPA實(shí)現(xiàn)查詢結(jié)果返回map或自定義的實(shí)體類
Spring Data JPA查詢結(jié)果返回map或自定義的實(shí)體類
在JPA中我們可以使用entityManager.createNativeQuery()來(lái)執(zhí)行原生的SQL語(yǔ)句,并且JPA的底層實(shí)現(xiàn)都是支持返回Map對(duì)象的。
例如:
- EclipseLink 的
query.setHint(QueryHints.RESULT_TYPE, ResultType.Map);
- Hibernate 的
query.unwrap(SQLQuery.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
- OpenJPA 的
QueryImpl impl = q.unwrap(QueryImpl.class); impl.setResultClass(Map.class);
本文中使用的是Spring Data JPA(Spring Data JPA 可以理解為 JPA 規(guī)范的再次封裝抽象,底層還是使用了 Hibernate 的 JPA 技術(shù)實(shí)現(xiàn)),遂用 Hibernate 的query.unwrap(SQLQuery.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP)。
1.工具類
@Component
public class EntityManagerUtil<T> {
@PersistenceContext
private EntityManager entityManager;
//1.返回map
public List<Map<String, Object>> getListMap(String sql){
Query nativeQuery=entityManager.createNativeQuery(sql);
nativeQuery.unwrap(SQLQuery.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
List resultList=nativeQuery.getResultList();
return resultList;
}
//2.返回自定義實(shí)體類
public List<T> nativeQueryResult(String sql, Class clazz) {
sql = Normalizer.normalize(sql, Normalizer.Form.NFKC);
sql = sql.replaceAll(".*([';]+|(--)+).*", "");
Query query = entityManager.createNativeQuery(sql);
List<T> queryList = query.unwrap(SQLQuery.class).setResultTransformer(Transformers.aliasToBean(clazz)).list();
return queryList;
}
}
2.具體應(yīng)用
//1.自動(dòng)注入
@Autowired
private EntityManagerUtil entityManagerUtil;
//1.返回map
String sql="sql語(yǔ)句";
List<Map> list=entityManagerUtil.getListMap(sql);
//2.1 返回自定義實(shí)體類(方法一)
List<實(shí)體類> list = entityManagerUtil.nativeQueryResult(sql, 實(shí)體類.class);
//2.2 返回自定義實(shí)體類(方法二 hql)
在hql中使用 select new 包名.類名(屬性1,屬性2……) from 實(shí)體類,同時(shí)在實(shí)體類中添加帶參的構(gòu)造方法,參數(shù)的個(gè)數(shù)和順序與(屬性1,屬性2……) 保持一致,這樣我們得到的list中存放的依然是實(shí)體類的對(duì)象,所查詢到的屬性得到了填充。
spingboot:jpa:Spring data jpa 返回map 結(jié)果集


@PersistenceContext
private EntityManager em;
/**
* 通過時(shí)間范圍查詢職位統(tǒng)計(jì)結(jié)果
* @param startMonth
* @param endMonth
* @return
*/
@Override
public String queryPositionByMonthOfYear(String startMonth, String endMonth) {
int sumNewPosn =0;
int sumCurrPosn =0;
int dailyAverage =0;
Map<String, Object> resultMap=null;
JSONObject jo =null;
JSONObject jod =null;
String endMonthTmp=null;
List<Map<String,Object>> lis = null;
try {
int tmp = Integer.valueOf(endMonth.split("-")[1])+1;
endMonthTmp=Integer.valueOf(endMonth.split("-")[0])+"-"+tmp;
String sql = "select left(statistic_time,7) time ,sum(new_position) newPosition ,sum(curr_position) nowRecruitposition from t_cal_positions " +
"where statistic_time > '"+startMonth+"' and statistic_time <'"+endMonthTmp+"' group by left(statistic_time,7)";
Query query = em.createNativeQuery(sql);
query.unwrap(org.hibernate.SQLQuery.class)
.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
List<Map<String, Object>> rows = query.getResultList();
if(null!=rows && rows.size()>0){
resultMap = new HashMap<String, Object>();
lis= new ArrayList<Map<String,Object>>();
for (Map<String, Object> map : rows) {
if(map.get("time").equals(endMonth)){
// int daynum = DateUtil.getDayOfMonth(Integer.valueOf(endMonth.split("-")[0]),Integer.valueOf(endMonth.split("-")[1]));
dailyAverage=Integer.valueOf(String.valueOf(map.get("nowRecruitposition")))/DateUtil.getDateOfMonth();
}
lis.add(map);
}
jo = new JSONObject();
jod = new JSONObject();
jod.put("dailyAverage",dailyAverage);
jod.put("list",lis);
jo.put("code", EnumHttpStatusType.success.getCode());
jo.put("msg",EnumHttpStatusType.success.getStatus());
jo.put("data",jod);
return jo.toString();
}
} catch (Exception e) {
e.printStackTrace();
}
return jo.toString();
}
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
攜程Apollo(阿波羅)安裝部署以及java整合實(shí)現(xiàn)
這篇文章主要介紹了攜程Apollo(阿波羅)安裝部署以及java整合實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-08-08
詳解Java使用JDBC連接MySQL數(shù)據(jù)庫(kù)
本文詳細(xì)講解了Java使用JDBC連接MySQL數(shù)據(jù)庫(kù)的方法,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-01-01
Java簡(jiǎn)單使用redis-zset實(shí)現(xiàn)排行榜
這篇文章主要介紹了Java簡(jiǎn)單使用redis-zset實(shí)現(xiàn)排行榜,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12
IntellJ idea使用FileWatch實(shí)時(shí)編譯less文件的方法
這篇文章主要介紹了IntellJ idea使用FileWatch實(shí)時(shí)編譯less文件的相關(guān)資料,需要的朋友可以參考下2018-02-02

