實用的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 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!