hibernate+spring 的泛型dao接口和和实现类..以及配置
1.泛型dao接口
package hibernate.basedao;import java.io.Serializable;import java.util.LinkedHashMap;import java.util.List;import co.th.tools.PageData;/** * 通用Dao父类实现的接?口,只提供常见的一些功能,其它特殊的功能,可以在子接口中定义。 * 事务也在需要的时候加到实现类中 * * @param <T> 实体类型 */public interface GenericDao<T> {public List<T> findTbyHql(String hql);/** * by this method you can get all information about T * @return */public List<T> findAll();/** * 和数据库同步 * @param entityClass 实体类 * @return */public void fulsh();/** * 获取记录总数 * @param entityClass 实体类 * @return */public long getCount(final String wherejpql, final Object[] queryParams);/** * 清除一级缓存的数据 */public void clear();/** * 保存实体 * @param entity 实体id */public void save(Object entity);/** * 更新实体 * @param entity 实体id */public void update(Object entity);/** * 删除实体 * @param entityClass 实体类 * @param entityids 实体id数组 */public void delete(Serializable ... entityids);/** * 获取实体 * @param <T> * @param entityClass 实体类 * @param entityId 实体id * @return */public T find(Serializable entityId) ;/** * 获取实体 * @param <T> * @param entityClass 实体类 * @param entityId 实体id * @return */public T get(Serializable entityId);/** * 获取分页数据 * @param <T> * @param entityClass 实体类 * @param firstindex 开始索引 * @param maxresult 需要获取的记录数 * @return */public PageData<T> getScrollData(int firstindex, int maxresult, String wherejpql, Object[] queryParams,LinkedHashMap<String, String> orderby);public PageData<T> getScrollData(int firstindex, int maxresult, String wherejpql, Object[] queryParams);public PageData<T> getScrollData(int firstindex, int maxresult, LinkedHashMap<String, String> orderby);public PageData<T> getScrollData(int firstindex, int maxresult);public PageData<T> getScrollData();public PageData<T> getScrollDataByHql( final int firstindex, final int maxresult, final String hql_search, final String hql_totalRecords);public int executeDML(final String hql);public int executeDML(final String sethql, Object[] values);public List<T> limitFindByHql(final int firstindex, final int maxresult,final String wherejpql, final Object[] queryParams,final LinkedHashMap<String, String> orderby);}2.泛型dao接口实现类
package hibernate.basedao;import java.io.Serializable;import java.sql.SQLException;import java.util.LinkedHashMap;import java.util.List;import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory;import org.hibernate.HibernateException;import org.hibernate.Query;import org.hibernate.Session;import org.springframework.orm.hibernate3.HibernateCallback;import org.springframework.orm.hibernate3.support.HibernateDaoSupport;import co.th.tools.GenericsUtils;import co.th.tools.PageData;@SuppressWarnings("unchecked")public abstract class GenericDaoImpl<T> extends HibernateDaoSupport implements GenericDao<T>{ protected Log logger = LogFactory.getLog(GenericDaoImpl.class);protected Class<T> entityClass = GenericsUtils.getSuperClassGenricType(this.getClass());public void clear() {getHibernateTemplate().clear(); }public void fulsh(){getHibernateTemplate().flush();}public void delete(Serializable... entityids) {for (int i = 0; i < entityids.length; i++) {T t = get(entityids[i]); if(t != null){getHibernateTemplate().delete(t);} }}public T find(Serializable entityId) {if(entityId == null){throw new RuntimeException(this.entityClass.getName()+ ":id is empty or null");}T t = null; t = get(entityId);return t;}public T get(Serializable entityId){if(entityId == null){throw new RuntimeException(this.entityClass.getName()+ ":id is empty or null");}return (T) getHibernateTemplate().get(this.entityClass, entityId);}public long getCount(final String wherejpql, final Object[] queryParams) {final String hql = "select count(o) from "+ getEntityName(this.entityClass)+ " o " + (wherejpql==null || "".equals(wherejpql.trim())? "": "where 1=1 "+ wherejpql); return (Long)getHibernateTemplate().execute(new HibernateCallback(){ public Object doInHibernate(Session session)throws HibernateException, SQLException { Query query = session.createQuery(hql);setQueryParams(query, queryParams);return query.uniqueResult();} });}public void save(Object entity) {getHibernateTemplate().save(entity);}public void update(Object entity) {getHibernateTemplate().update(entity);}@SuppressWarnings("unchecked")public PageData<T> getScrollData(final int firstindex, final int maxresult,final String wherejpql, final Object[] queryParams,final LinkedHashMap<String, String> orderby) {final PageData qr = new PageData<T>();final String entityname = getEntityName(this.entityClass);return (PageData<T>)getHibernateTemplate().execute(new HibernateCallback(){ public Object doInHibernate(Session session)throws HibernateException, SQLException { Query query = session.createQuery("select o from "+ entityname+ " o "+(wherejpql==null || "".equals(wherejpql.trim())? "": "where 1=1 "+ wherejpql)+ buildOrderby(orderby));setQueryParams(query, queryParams);if(firstindex!=-1 && maxresult!=-1) query.setFirstResult(firstindex).setMaxResults(maxresult);qr.setResultlist(query.list());query = session.createQuery("select count(o) from "+ entityname+ " o "+(wherejpql==null || "".equals(wherejpql.trim())? "": "where 1=1 "+ wherejpql));setQueryParams(query, queryParams);qr.setTotalRecords((Long)query.uniqueResult());return qr; }});}@SuppressWarnings("unchecked")public PageData<T> getScrollDataByHql(final int firstindex, final int maxresult,final String hql_search, final String hql_totalRecords) {final PageData qr = new PageData<T>();//final String entityname = getEntityName(this.entityClass);return (PageData<T>)getHibernateTemplate().execute(new HibernateCallback(){ public Object doInHibernate(Session session)throws HibernateException, SQLException { Query query = null; query = session.createQuery(hql_search);if(firstindex!=-1 && maxresult!=-1) query.setFirstResult(firstindex).setMaxResults(maxresult);qr.setResultlist(query.list()); query = session.createQuery(hql_totalRecords);qr.setTotalRecords((Long)query.uniqueResult()); return qr; }});}/** * 设置查询条件的参数 * @param query * @param queryParams */protected static void setQueryParams(Query query, Object[] queryParams){if(queryParams!=null && queryParams.length>0){for(int i=0; i<queryParams.length; i++){query.setParameter(i, queryParams[i]);}}}/** * 组装order by语句 * @param orderby * @return */protected static String buildOrderby(LinkedHashMap<String, String> orderby){StringBuffer orderbyql = new StringBuffer("");if(orderby!=null && orderby.size()>0){orderbyql.append(" order by ");for(String key : orderby.keySet()){orderbyql.append("o.").append(key).append(" ").append(orderby.get(key)).append(",");}orderbyql.deleteCharAt(orderbyql.length()-1);}return orderbyql.toString();}public PageData<T> getScrollData(int firstindex, int maxresult,String wherejpql, Object[] queryParams) {return getScrollData(firstindex, maxresult, wherejpql, queryParams, null);}public PageData<T> getScrollData(int firstindex, int maxresult,LinkedHashMap<String, String> orderby) {return getScrollData(firstindex, maxresult, null, null, orderby);}public PageData<T> getScrollData(int firstindex, int maxresult) {return getScrollData(firstindex, maxresult, null, null, null);}public PageData<T> getScrollData() {return getScrollData(-1, -1);}/** * 获取实体的名称 * @param <E> * @param clazz 实体类 * @return */protected static <E> String getEntityName(Class<E> clazz){String entityname = clazz.getSimpleName();return entityname;}public List<T> findAll(){List<T> list = getHibernateTemplate().loadAll(entityClass);return list;}public List<T> findTbyHql(String hql){List<T> list = getHibernateTemplate().find(hql);return list;}public int executeDML(final String hql){Integer result = 0; result = getHibernateTemplate().bulkUpdate(hql);return result;}public int executeDML(final String sethql, Object[] values){Integer result = 0;final String entityname = getEntityName(this.entityClass);String hql = "update " + entityname + " o " + sethql ;result = getHibernateTemplate().bulkUpdate(hql, values);return result;}@SuppressWarnings("unchecked")public List<T> limitFindByHql(final int firstindex, final int maxresult,final String wherejpql, final Object[] queryParams,final LinkedHashMap<String, String> orderby) {final String entityname = getEntityName(this.entityClass);return (List<T>)getHibernateTemplate().execute(new HibernateCallback(){ public Object doInHibernate(Session session)throws HibernateException, SQLException { Query query = session.createQuery("select o from "+ entityname+ " o "+(wherejpql==null || "".equals(wherejpql.trim())? "": "where 1=1 "+ wherejpql)+ buildOrderby(orderby));setQueryParams(query, queryParams);if(firstindex!=-1 && maxresult!=-1) query.setFirstResult(firstindex).setMaxResults(maxresult); return query.list(); }});}}3.PageData源代码
public class PageData<T> {private List<T> resultlist;private long TotalRecords;public List<T> getResultlist() {return resultlist;}public void setResultlist(List<T> resultlist) {this.resultlist = resultlist;}public long getTotalRecords() {return TotalRecords;}public void setTotalRecords(long totalRecords) {TotalRecords = totalRecords;}}4.GenericsUtils 源代码
public class GenericsUtils {/** * 通过反射,获得指定类的父类的泛型参数的实际类型. 如BuyerServiceBean extends DaoSupport<Buyer> * * @param clazz clazz 需要反射的类,该类必须继承范型父类 * @param index 泛型参数所在索引,从0开始. * @return 范型参数的实际类型, 如果没有实现ParameterizedType接口,即不支持泛型,所以直接返回<code>Object.class</code> */ @SuppressWarnings("unchecked")public static Class getSuperClassGenricType(Class clazz, int index) { Type genType = clazz.getGenericSuperclass();//得到泛型父类 //如果没有实现ParameterizedType接口,即不支持泛型,直接返回Object.class if (!(genType instanceof ParameterizedType)) { return Object.class; } //返回表示此类型实际类型参数的Type对象的数组,数组里放的都是对应类型的Class, 如BuyerServiceBean extends DaoSupport<Buyer,Contact>就返回Buyer和Contact类型 Type[] params = ((ParameterizedType) genType).getActualTypeArguments(); if (index >= params.length || index < 0) { throw new RuntimeException("你输入的索引"+ (index<0 ? "不能小于0" : "超出了参数的总数")); } if (!(params[index] instanceof Class)) { return Object.class; } return (Class) params[index]; }/** * 通过反射,获得指定类的父类的第一个泛型参数的实际类型. 如BuyerServiceBean extends DaoSupport<Buyer> * * @param clazz clazz 需要反射的类,该类必须继承泛型父类 * @return 泛型参数的实际类型, 如果没有实现ParameterizedType接口,即不支持泛型,所以直接返回<code>Object.class</code> */ @SuppressWarnings("unchecked")public static Class getSuperClassGenricType(Class clazz) { return getSuperClassGenricType(clazz,0); }/** * 通过反射,获得方法返回值泛型参数的实际类型. 如: public Map<String, Buyer> getNames(){} * * @param Method method 方法 * @param int index 泛型参数所在索引,从0开始. * @return 泛型参数的实际类型, 如果没有实现ParameterizedType接口,即不支持泛型,所以直接返回<code>Object.class</code> */ @SuppressWarnings("unchecked")public static Class getMethodGenericReturnType(Method method, int index) { Type returnType = method.getGenericReturnType(); if(returnType instanceof ParameterizedType){ ParameterizedType type = (ParameterizedType) returnType; Type[] typeArguments = type.getActualTypeArguments(); if (index >= typeArguments.length || index < 0) { throw new RuntimeException("你输入的索引"+ (index<0 ? "不能小于0" : "超出了参数的总数")); } return (Class)typeArguments[index]; } return Object.class; }/** * 通过反射,获得方法返回值第一个泛型参数的实际类型. 如: public Map<String, Buyer> getNames(){} * * @param Method method 方法 * @return 泛型参数的实际类型, 如果没有实现ParameterizedType接口,即不支持泛型,所以直接返回<code>Object.class</code> */ @SuppressWarnings("unchecked")public static Class getMethodGenericReturnType(Method method) { return getMethodGenericReturnType(method, 0); } /** * 通过反射,获得方法输入参数第index个输入参数的所有泛型参数的实际类型. 如: public void add(Map<String, Buyer> maps, List<String> names){} * * @param Method method 方法 * @param int index 第几个输入参数 * @return 输入参数的泛型参数的实际类型集合, 如果没有实现ParameterizedType接口,即不支持泛型,所以直接返回空集合 */ @SuppressWarnings("unchecked")public static List<Class> getMethodGenericParameterTypes(Method method, int index) { List<Class> results = new ArrayList<Class>(); Type[] genericParameterTypes = method.getGenericParameterTypes(); if (index >= genericParameterTypes.length ||index < 0) { throw new RuntimeException("你输入的索引"+ (index<0 ? "不能小于0" : "超出了参数的总数")); } Type genericParameterType = genericParameterTypes[index]; if(genericParameterType instanceof ParameterizedType){ ParameterizedType aType = (ParameterizedType) genericParameterType; Type[] parameterArgTypes = aType.getActualTypeArguments(); for(Type parameterArgType : parameterArgTypes){ Class parameterArgClass = (Class) parameterArgType; results.add(parameterArgClass); } return results; } return results; }/** * 通过反射,获得方法输入参数第一个输入参数的所有泛型参数的实际类型. 如: public void add(Map<String, Buyer> maps, List<String> names){} * * @param Method method 方法 * @return 输入参数的泛型参数的实际类型集合, 如果没有实现ParameterizedType接口,即不支持泛型,所以直接返回空集合 */ @SuppressWarnings("unchecked")public static List<Class> getMethodGenericParameterTypes(Method method) { return getMethodGenericParameterTypes(method, 0); }/** * 通过反射,获得Field泛型参数的实际类型. 如: public Map<String, Buyer> names; * * @param Field field 字段 * @param int index 泛型参数所在索引,从0开始. * @return 泛型参数的实际类型, 如果没有实现ParameterizedType接口,即不支持泛型,所以直接返回<code>Object.class</code> */ @SuppressWarnings("unchecked")public static Class getFieldGenericType(Field field, int index) { Type genericFieldType = field.getGenericType(); if(genericFieldType instanceof ParameterizedType){ ParameterizedType aType = (ParameterizedType) genericFieldType; Type[] fieldArgTypes = aType.getActualTypeArguments(); if (index >= fieldArgTypes.length || index < 0) { throw new RuntimeException("你输入的索引"+ (index<0 ? "不能小于0" : "超出了参数的总数")); } return (Class)fieldArgTypes[index]; } return Object.class; }/** * 通过反射,获得Field泛型参数的实际类型. 如: public Map<String, Buyer> names; * * @param Field field 字段 * @param int index 泛型参数所在索引,从0开始. * @return 泛型参数的实际类型, 如果没有实现ParameterizedType接口,即不支持泛型,所以直接返回<code>Object.class</code> */ @SuppressWarnings("unchecked")public static Class getFieldGenericType(Field field) { return getFieldGenericType(field, 0); }}5.用于分页的PageIndex和PageView
public class PageIndex {private long startindex;private long endindex;public PageIndex(long startindex, long endindex) {this.startindex = startindex;this.endindex = endindex;}public long getStartindex() {return startindex;}public void setStartindex(long startindex) {this.startindex = startindex;}public long getEndindex() {return endindex;}public void setEndindex(long endindex) {this.endindex = endindex;}}public class PageView<T> {/** 分页数据 **/private List<T> records;/** 页码开始索引和结束索引 **/private PageIndex pageindex;/** 总页数 **/private long totalpage = 1;/** 每页显示记录数 **/private int maxresult = 12;/** 当前页 **/private int currentpage = 1;/** 总记录数 **/private long totalrecord;/** 尾页 **/private int lastpage;/** 页码数量 **/private int pagecode = 15;/** 要获取记录的开始索引 **/public int getFirstResult() {return (this.currentpage-1)*this.maxresult;}/**取得首页**/public int getTopPageNo() {return 1;}/** 取得尾页**/public long getBottomPageNo() {return getTotalpage();}/**上一页**/public int getPreviousPageNo() {if (currentpage <= 1) {return 1;}return currentpage - 1;}/**下一页* */public long getNextPageNo() {if (currentpage >= getBottomPageNo()) {return getBottomPageNo();}return currentpage + 1;}public int getPagecode() {return pagecode;}public void setPagecode(int pagecode) {this.pagecode = pagecode;}public PageView(int maxresult, int currentpage) {this.maxresult = maxresult;this.currentpage = currentpage;}public void setPageData(PageData<T> pageData){setTotalrecord(pageData.getTotalRecords());setRecords(pageData.getResultlist());}public long getTotalrecord() {return totalrecord;}public void setTotalrecord(long totalrecord) {this.totalrecord = totalrecord;setTotalpage(this.totalrecord%this.maxresult==0? this.totalrecord/this.maxresult : this.totalrecord/this.maxresult+1);}public List<T> getRecords() {return records;}public void setRecords(List<T> records) {this.records = records;}public PageIndex getPageindex() {return pageindex;}public long getTotalpage() {return totalpage;}public void setTotalpage(long totalpage) {this.totalpage = totalpage == 0 ? 1 : totalpage;this.pageindex = getPageIndex(pagecode, currentpage, totalpage);}public int getMaxresult() {return maxresult;}public int getCurrentpage() {return currentpage;}public int getLastpage() {return lastpage;} public static PageIndex getPageIndex(long viewpagecount, int currentPage, long totalpage){long startpage = currentPage-(viewpagecount%2==0? viewpagecount/2-1 : viewpagecount/2);long endpage = currentPage+viewpagecount/2;if(startpage<1){startpage = 1;if(totalpage>=viewpagecount) endpage = viewpagecount;else endpage = totalpage;}if(endpage>totalpage){endpage = totalpage;if((endpage-viewpagecount)>0) startpage = endpage-viewpagecount+1;else startpage = 1;}return new PageIndex(startpage, endpage); } public PageView() { }public void setCurrentpage(int currentpage) {this.currentpage = currentpage;}public void setMaxresult(int maxresult) {this.maxresult = maxresult;}}配置
<!-- 配置sessioFactory --><bean id="sessionFactory"ref="sessionFactory"></property> </bean> <bean id="genericDao" abstract="true" ref="hibernateTemplate"/> <property name="sessionFactory" ref="sessionFactory"/></bean> <!-- 配置事务管理器 --><bean id="transactionManager"/></property></bean><!-- 配置事务的传播特性 --><tx:advice id="txAdvice" transaction-manager="transactionManager"><tx:attributes><tx:method name="add*" propagation="REQUIRED" /><tx:method name="assign*" propagation="REQUIRED" /><tx:method name="modify*" propagation="REQUIRED" /><tx:method name="del*" propagation="REQUIRED" /><tx:method name="update*" propagation="REQUIRED" /><tx:method name="*" read-only="true" /></tx:attributes></tx:advice><aop:config proxy-target-/><aop:advisor advice-ref="txAdvice"pointcut="execution (* co.th.csl.*.*.service.*.*(..))" /><!-- ************************for module:csl**************************************** --><!-- ************************for module:content**************************************** --><aop:advisor advice-ref="txAdvice"pointcut="execution (* co.th.content.*.*.service.*.*(..))" /><!-- ************************for module:content**************************************** --></aop:config><!-- 配置哪些类哪些方法使用事务 --><!-- <aop:config>配置切入点(定义哪些方法要进行事务处理) <aop:pointcut id="allManager"expression="execution(* co.th.csl.contact.service.*.*(..))" />定义advice <aop:advisor advice-ref="txAdvice" pointcut-ref="allManager" /></aop:config>-->
at org.springframework.orm.hibernate3.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:676)
at org.springframework.orm.hibernate3.HibernateAccessor.convertHibernateAccessException(HibernateAccessor.java:412)
at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:424)