實用的JPA封裝工具類
該封裝是在spring+JPA 的基礎上完成的。
BaseDaoForJPA.java
package com.abs.dao.base; import java.util.LinkedHashMap; import java.util.List; import java.util.Set; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import javax.persistence.Query; public abstract class BaseDaoForJPA { @PersistenceContext private EntityManager entityManager; /*** 保存實體,實體必須使用符合JPA規范的注解進行配置 * 保存之后會給主鍵自動賦值(具體請查閱JPA EntityManager.persist 文檔說明) */ protected final void executeSave(Object entity){ this.entityManager.persist(entity); } /** * 更新實體,實體必須使用符合JPA規范的注解進行配置 * 保存之后會給主鍵自動賦值(具體請查閱JPA EntityManager.merge 文檔說明) */ protected final void executeUpdate(Object entity){ this.merge(entity); } /** * 根據主鍵ID查詢實體,實體必須使用符合JPA規范的注解進行配置 * @param id 主鍵 * @param clazz 需要查詢的實體類 */ protected final <T>T queryForEntity(Object id,Class<T> clazz){ T entity = entityManager.find(clazz, id); return entity; } /** * 根據實體Class 查詢改實體所有的記錄, 實體必須使用符合JPA規范的注解進行配置 * 由于是查詢所有記錄,輸出效率考慮 請慎重使用 * @param clazz 需要查詢的實體類 */ protected final <T> List<T> queryForList(Class<T> clazz){ return this.queryForList(clazz, null, null); } /** * 更新實體,實體必須使用符合JPA規范的注解進行配置 * @param HQL 語言 <code>update User o set o.userName = ? where o.id = ?</code> * @param 預處理參數 <code>new Object{"張三",1} ; </code> */ protected final boolean executeUpdate(String updateHQL,Object[] parameterArray){ return this.execute(updateHQL, parameterArray); } /** * 更新實體,實體必須使用符合JPA規范的注解進行配置 * @param HQL 語言 <code>update User o set o.userName = ? where o.id = ?</code> */ protected final boolean executeUpdate(String updateHQL){ return this.executeUpdate(updateHQL, null); } /** * 刪除實體,實體必須使用符合JPA規范的注解進行配置 */ protected final <T> void executeDelete(T entity){ this.entityManager.remove(entity); } /** * 根據主鍵ID刪除實體,實體必須使用符合JPA規范的注解進行配置 * @param id 主鍵 * @param clazz 需要刪除實體類 */ protected final <T> void executeDelete(Class<T> clazz, Object id){ this.executeDelete(this.queryForEntity(id, clazz)); } /** * 刪除實體,實體必須使用符合JPA規范的注解進行配置 * @param HQL 語言 <code>delete User o where o.id = ?</code> */ protected final <T> boolean executeDelete(String deleteHQL,Object[]parameterArray){ return this.execute(deleteHQL, parameterArray); } /** * 根據實體Class,條件,參數 查詢記錄, 實體必須使用符合JPA規范的注解進行配置 * @param clazz 需要查詢的實體類 * @param conditions put("userName","like") * @param parameterArray new Object[]{"%zhang%"} */ protected final <T> List <T> queryForList(Class<T> clazz,LinkedHashMap<String,String> conditions,Object[]parameterArray){ return this.queryForList(clazz, conditions, parameterArray, null); } /** * 根據實體Class,條件,參數 查詢記錄,可以對相應的記錄進行排序 實體必須使用符合JPA規范的注解進行配置 * @param clazz 需要查詢的實體類 * @param conditions put("userName","like") * @param parameterArray new Object[]{"%zhang%"} * @param order put("id","asc") */ protected final <T> List <T> queryForList(Class<T> clazz,LinkedHashMap<String,String> conditions,Object[]parameterArray,LinkedHashMap<String,String>orderBy){ String queryHQL = getQueryString(clazz,conditions,orderBy); return queryForList(queryHQL,parameterArray); } /** * 使用HQL 進行實體的查詢 實體必須使用符合JPA規范的注解進行配置 * @param queryHQL select o from User o where o.id = 36 */ protected final <T> List <T> queryForList(String queryHQL){ return this.queryForList(queryHQL, null); } /** * 根據實體Class 查詢改實體所有的記錄,可以對相應的記錄進行排序 實體必須使用符合JPA規范的注解進行配置 * 由于是查詢所有記錄,輸出效率考慮 請慎重使用 * @param clazz 需要查詢的實體類 * @param order put("id","asc") */ protected final <T> List<T> queryForList(Class<T>clazz,LinkedHashMap<String,String>orderBy){ return this.queryForList(clazz, null, null, orderBy); } /** * 使用HQL 進行實體的查詢 實體必須使用符合JPA規范的注解進行配置 * @param queryHQL select o from User o where o.id =? * @param parameterArray new Object[]{36} */ protected final <T> List <T> queryForList(String queryHQL,Object[]parameterArray){ return this.queryForList(queryHQL, parameterArray, 0, 0); } /** * 使用HQL查詢整數(任何可以返回整數的HQL語句) 實體必須使用符合JPA規范的注解進行配置 * @param queryHQL select o.id from User o where o.id =36 */ protected final int queryForInt(String queryIntHQL){ return this.queryForInt(queryIntHQL, null); } /** * 使用HQL查詢整數(任何可以返回整數的HQL語句) 實體必須使用符合JPA規范的注解進行配置 * @param queryHQL select o.id from User o where o.id =36 * @param parameterArray new Object[]{36} */ protected final int queryForInt(String queryIntHQL,Object[]parameterArray){ Query query = entityManager.createQuery(queryIntHQL); setQueryParameterValues(parameterArray,query); int result = Integer.parseInt(query.getSingleResult().toString()); return result; } final List queryForList(String queryHQL,Object[]parameterArray,int firstResult,int maxResult){ Query query = entityManager.createQuery(queryHQL); setQueryParameterValues(parameterArray,query); if(firstResult>=0) query.setFirstResult(firstResult); if(maxResult>0) query.setMaxResults(maxResult); return query.getResultList(); } final String getOrderBy(LinkedHashMap<String,String> orderBy){ if(orderBy==null||orderBy.size()==0)return ""; StringBuilder orderByBuilder = new StringBuilder(" order by "); Set<String> orderFields = orderBy.keySet(); for(String orderField : orderFields){ orderByBuilder.append(" o.").append(orderField).append(" ").append(orderBy.get(orderField)).append(","); } orderByBuilder.delete(orderByBuilder.length()-1, orderByBuilder.length()); return orderByBuilder.toString(); } final void setQueryParameterValues(Object[]parameterArray,Query query){ if(parameterArray==null||parameterArray.length==0)return; for(int i=0 ; i<parameterArray.length;i++){ query.setParameter(i+1, parameterArray[i]); } } final <T> String getQueryString(Class<T> clazz,LinkedHashMap<String,String> conditions,LinkedHashMap<String,String>orderBy){ StringBuilder queryBuilder = new StringBuilder(" select o from "); queryBuilder.append(getEntityFullName(clazz)).append(" o ").append(getCondtitons(conditions)).append(getOrderBy(orderBy)); return queryBuilder.toString(); } final <T> String getEntityFullName(Class<T> clazz){ return clazz.getName(); } final String getCondtitons(LinkedHashMap<String,String> conditions){ StringBuilder conditionsBuilder = new StringBuilder(" where 1=1 "); if(conditions==null||conditions.size()==0){ return conditionsBuilder.toString(); } Set<String>conditonFields = conditions.keySet(); for(String conditionField : conditonFields){ conditionsBuilder.append(" and o."); conditionsBuilder.append(conditionField); conditionsBuilder.append(" "); conditionsBuilder.append(conditions.get(conditionField)); conditionsBuilder.append(" ? "); } return conditionsBuilder.toString(); } private final boolean execute(String execuetHQL,Object[]parameterArray){ Query query = entityManager.createQuery(execuetHQL); this.setQueryParameterValues(parameterArray, query); return query.executeUpdate()>0?true:false; } private final <T> T merge(T entity){ return entityManager.merge(entity); }
} </pre>
PagingationDaoSupportForJPA.java
package com.abs.dao.base; import java.util.LinkedHashMap; import org.springframework.jdbc.BadSqlGrammarException; import com.abs.util.PageObject; public abstract class PagingationDaoSupportForJPA extends BaseDaoForJPA { /*** 根據實體 當前頁碼,單頁記錄數 Class,條件,參數 分頁查詢記錄,并且排序 實體必須使用符合JPA規范的注解進行配置 * @param currentPage 當前頁碼 * @param pageSize 單頁記錄數 * @param preparedParameterArray new Object[]{13} * @param queryForListQHL * </br>HQL語句 <code>select o from User o where o.id >? * </br>或者from User o where o.id >?</code> * */ protected final <T>PageObject<T> queryForPaginationList(int currentPage, int pageSize, String queryForListHQL,Object[] preparedParameterArray) { int dataCount = queryCount(queryForListHQL, preparedParameterArray); PageObject<T> pageObject = new PageObject<T>(dataCount, currentPage,pageSize); pageObject.setPageList(queryForList(queryForListHQL, preparedParameterArray, pageObject.getStartPoint(),pageObject.getEndPoint())); return pageObject; } /** * 根據實體 當前頁碼,單頁記錄數 Class,條件,參數 分頁查詢記錄,并且排序 實體必須使用符合JPA規范的注解進行配置 * @param currentPage 當前頁碼 * @param pageSize 單頁記錄數 * @param queryForListQHL * </br>HQL語句 <code>select o from User o where o.id > 10 * </br>或者from User o where o.id >10</code> */ protected final <T>PageObject<T> queryForPaginationList(int currentPage, int pageSize, String queryForListHQL){ return this.queryForPaginationList(currentPage, pageSize, queryForListHQL,null); } /** * 根據實體 當前頁碼,單頁記錄數 Class,條件,參數 分頁查詢記錄,并且排序 實體必須使用符合JPA規范的注解進行配置 * @param currentPage 當前頁碼 * @param pageSize 單頁記錄數 * @param clazz 需要查詢的實體類 * @param conditions put("userName","like") * @param parameterArray new Object[]{"%zhang%"} * @param orderBy put("id","asc") */ protected final<T>PageObject<T> queryForPaginationList(int currentPage,int pageSize,Class<T> clazz,LinkedHashMap<String,String>conditions,Object[]preparedParameterArray,LinkedHashMap<String,String> orderBy){ String queryForListHQL = this.getQueryString(clazz, conditions, orderBy); return this.queryForPaginationList(currentPage, pageSize, queryForListHQL, preparedParameterArray); } /** * 根據實體 當前頁碼,單頁記錄數 Class,條件,參數 分頁查詢記錄 實體必須使用符合JPA規范的注解進行配置 * @param currentPage 當前頁碼 * @param pageSize 單頁記錄數 * @param clazz 需要查詢的實體類 * @param conditions put("userName","like") * @param parameterArray new Object[]{"%zhang%"} */ protected final<T>PageObject<T>queryForPaginationList(int currentPage,int pageSize,Class<T> clazz,LinkedHashMap<String,String>conditions,Object[]preparedParameterArray){ return queryForPaginationList(currentPage, pageSize,clazz,conditions,preparedParameterArray,null); } /** * 根據實體 當前頁碼,單頁記錄數 Class 分頁查詢記錄 實體必須使用符合JPA規范的注解進行配置 * @param currentPage 當前頁碼 * @param pageSize 單頁記錄數 * @param clazz 需要查詢的實體類 */ protected final<T>PageObject<T> queryForPaginationList(int currentPage,int pageSize,Class<T> clazz){ return queryForPaginationList(currentPage, pageSize,clazz,null,null); } /** * 根據實體 當前頁碼,單頁記錄數 Class 分頁查詢記錄 實體必須使用符合JPA規范的注解進行配置 默認單頁數據記錄數為10 * @param currentPage 當前頁碼 * @param clazz 需要查詢的實體類 */ protected final<T>PageObject<T> queryForPaginationList(int currentPage,Class<T> clazz){ return queryForPaginationList(currentPage,clazz,null,null); } /** * 根據實體 當前頁碼,單頁記錄數 Class,條件,參數 分頁查詢記錄 實體必須使用符合JPA規范的注解進行配置 默認單頁數據記錄數為10 * @param currentPage 當前頁碼 * @param clazz 需要查詢的實體類 * @param conditions put("userName","like") * @param parameterArray new Object[]{"%zhang%"} */ protected final<T>PageObject<T>queryForPaginationList(int currentPage,Class<T> clazz,LinkedHashMap<String,String>conditions,Object[]preparedParameterArray){ return queryForPaginationList(currentPage,clazz,conditions,preparedParameterArray,null); } /** * 根據實體 當前頁碼,單頁記錄數 Class,條件,參數 分頁查詢記錄,并且排序 實體必須使用符合JPA規范的注解進行配置 默認單頁數據記錄數為10 * @param currentPage 當前頁碼 * @param pageSize 單頁記錄數 * @param preparedParameterArray new Object[]{13} * @param queryForListQHL * </br>HQL語句 <code>select o from User o where o.id >? * </br>或者from User o where o.id >?</code> * */ protected final <T>PageObject<T> queryForPaginationList(int currentPage,String queryForListHQL,Object[] preparedParameterArray) { int dataCount = queryCount(queryForListHQL, preparedParameterArray); PageObject<T> pageObject = new PageObject<T>(dataCount, currentPage); pageObject.setPageList(queryForList(queryForListHQL, preparedParameterArray, pageObject.getStartPoint(),pageObject.getEndPoint())); return pageObject; } /** * 根據實體 當前頁碼,單頁記錄數 Class,條件,參數 分頁查詢記錄,并且排序 實體必須使用符合JPA規范的注解進行配置 默認單頁數據記錄數為10 * @param currentPage 當前頁碼 * @param pageSize 單頁記錄數 * @param queryForListQHL * </br>HQL語句 <code>select o from User o where o.id > 10 * </br>或者from User o where o.id >10</code> */ protected final <T>PageObject<T> queryForPaginationList(int currentPage, String queryForListHQL){ return this.queryForPaginationList(currentPage,queryForListHQL,null); } /** * 根據實體 當前頁碼,單頁記錄數 Class,條件,參數 分頁查詢記錄,并且排序 實體必須使用符合JPA規范的注解進行配置 默認單頁數據記錄數為10 * @param currentPage 當前頁碼 * @param clazz 需要查詢的實體類 * @param conditions put("userName","like") * @param parameterArray new Object[]{"%zhang%"} * @param orderBy put("id","asc") */ protected final<T>PageObject<T> queryForPaginationList(int currentPage,Class<T> clazz,LinkedHashMap<String,String>conditions,Object[]preparedParameterArray,LinkedHashMap<String,String> orderBy){ String queryForListHQL = this.getQueryString(clazz, conditions, orderBy); return this.queryForPaginationList(currentPage, queryForListHQL, preparedParameterArray); } private final int queryCount(String queryForListHQL,Object[] preparedParameterArray) { StringBuilder countHQLBuilder = new StringBuilder(" select count(*) "); try { countHQLBuilder.append(queryForListHQL.substring(queryForListHQL.toLowerCase().indexOf("from"))); } catch (RuntimeException ex) { throw new BadSqlGrammarException("SQL : ", queryForListHQL, null); } return queryForInt(countHQLBuilder.toString(), preparedParameterArray); }
}</pre></div>
PageObject.java
package com.abs.util; import java.util.ArrayList; import java.util.List; /** * @author Yi Su * @param <T> 泛型:like List<T></br> */ public class PageObject<T> { private int currentPage; private int dataCount; private int pageSize; private int maxPage; private List<T> pageList; private int startPoint; private int endPoint; private PaginationStrategy paginationStrategy; List<Integer> pageNumberList; public List<Integer> getPageNumberList() { return pageNumberList; } /** * @param dataCount 總數據數 * @param currentPage 當前頁 * @param pageSize 頁面大小 * 注: 默認分頁邏輯 startPoint & endPoint 是oracle實現</br> * 如果需要使用到其他數據庫請實現PaginationStrategy接口</br> * 使用該類的 setPaginationStrategy 方法獲得相應的實現</br> */ public PageObject(int dataCount, int currentPage) { this.pageSize = 10; this.dataCount = dataCount; this.currentPage = currentPage; maxPage = dataCount % pageSize == 0 ? dataCount / pageSize : dataCount/ pageSize + 1; paginationStrategy = new PaginaionStrategyForJPA(); setDataPoint(paginationStrategy); setPageNumberList(); } private void setPageNumberList(){ this.pageNumberList = new ArrayList<Integer>(); // 1 2 3 4 5 6 7 int pageNumber = currentPage-3; while(pageNumber<=0){ pageNumber++; } int count = 0; while(pageNumber<=maxPage-1&&count < 7){ count ++; this.pageNumberList.add(pageNumber); pageNumber++; } } /** * @param dataCount 總數據數 * @param currentPage 當前頁 * @param pageSize 頁面大小 * 注: 默認分頁邏輯 startPoint & endPoint 是oracle實現</br> * 如果需要使用到其他數據庫請實現PaginationStrategy接口</br> * 使用該類的 setPaginationStrategy 方法獲得相應的實現</br> */ public PageObject(int dataCount, int currentPage,int pageSize) { if(pageSize==0)throw new IllegalArgumentException(" 單頁數據設置 [pageSize]不能為小于等于 0 當前[pageSize]的值是 : "+pageSize); this.pageSize = pageSize; this.dataCount = dataCount; this.currentPage = currentPage; maxPage = dataCount % pageSize == 0 ? dataCount / pageSize : dataCount/ pageSize + 1; paginationStrategy = new PaginaionStrategyForJPA(); setDataPoint(paginationStrategy); setPageNumberList(); } private void setDataPoint(PaginationStrategy paginationStrategy){ paginationStrategy.setDataPoint(currentPage, pageSize); startPoint = paginationStrategy.getStartPoint(); endPoint = paginationStrategy.getEndPoint(); } /** * 默認的實現是 PaginationStrategyForOracle * 如果需要實現其他數據庫的分頁邏輯,請繼承 PaginationStrategy,傳入當前頁面和頁面大小設置不同數據庫的分頁 * @param paginationStrategy */ public void setPaginationStrategy(PaginationStrategy paginationStrategy){ this.paginationStrategy = paginationStrategy; setDataPoint(paginationStrategy); } /** * 獲得當前頁碼 * @return 當前頁碼 */ public int getCurrentPage() { return currentPage; } /** * 獲得單頁數據數 * @return 單頁數據數 */ public int getPageSize() { return pageSize; } /** * 獲得一共有多少頁 * @return 一共有多少頁 */ public int getMaxPage() { return maxPage; } /** * 獲得總數據數 * @return 總數據數 */ public int getDataCount() { return dataCount; } /** * 獲得分頁起始點 * @return 分頁起始點 */ public int getStartPoint() { return startPoint; } /** * 獲得分頁結束點 * @return 分頁結束點 */ public int getEndPoint() { return endPoint; } /** * 設置分頁對象集合 * @return 分頁對象集合 */ public List<T> getPageList() { return pageList; } /** * 獲得分頁對象集合 * @param pageList 分頁對象集合 */ public void setPageList(List<T> pageList) { this.pageList =pageList; } @Override public String toString() { StringBuilder pageObjectPrintBuilder = new StringBuilder(); pageObjectPrintBuilder.append(" 當前頁碼 ").append(currentPage).append(" 總數據數 ").append(dataCount); pageObjectPrintBuilder.append(" 起始點 ").append(startPoint).append(" 結束點 ").append(endPoint); pageObjectPrintBuilder.append(" 總頁數 ").append(maxPage). append(" 單頁數據數 ").append(pageSize); return pageObjectPrintBuilder.toString(); } }PaginaionStrategyForJPA.java
package com.abs.util; public class PaginaionStrategyForJPA implements PaginationStrategy{ private int startPoint; private int endPoint; public int getEndPoint() { return endPoint; } public int getStartPoint() { return startPoint; } public void setDataPoint(int currentPage,int pageSize) { startPoint= (currentPage - 1) * pageSize; endPoint = pageSize; } }PaginationStrategy.java
package com.abs.util; public interface PaginationStrategy { /** * 獲取數據結束點 * @return */ public int getStartPoint(); /** * 獲取數據起始點 * @return */ public int getEndPoint(); /** * 設置起分頁始點和結束點 * @param currentPage * @param pageSize */ public void setDataPoint(int currentPage,int pageSize); }本文由用戶 openkk 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!