实用的JPA封装工具类

openkk 12年前

该封装是在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);    }      } 

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);   }  }

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);  }