实用的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); }