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; /** * 通過(guò)時(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),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-08-08Spring事件監(jiān)聽(tīng)基本原理與使用詳解
這篇文章主要介紹了Spring事件監(jiān)聽(tīng)基本原理與使用詳解,Spring的事件監(jiān)聽(tīng)機(jī)制和發(fā)布訂閱機(jī)制是很相似的:發(fā)布了一個(gè)事件后,監(jiān)聽(tīng)該類型事件的所有監(jiān)聽(tīng)器會(huì)觸發(fā)相應(yīng)的處理邏輯,需要的朋友可以參考下2024-01-01詳解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-01Java簡(jiǎn)單使用redis-zset實(shí)現(xiàn)排行榜
這篇文章主要介紹了Java簡(jiǎn)單使用redis-zset實(shí)現(xiàn)排行榜,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12IntellJ idea使用FileWatch實(shí)時(shí)編譯less文件的方法
這篇文章主要介紹了IntellJ idea使用FileWatch實(shí)時(shí)編譯less文件的相關(guān)資料,需要的朋友可以參考下2018-02-02