實用的JPA封裝工具類

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