package com.guwenren.service.base; import java.beans.Introspector; import java.beans.PropertyDescriptor; import java.io.Serializable; import java.lang.reflect.Method; import java.util.LinkedHashMap; import javax.annotation.Resource; import javax.persistence.EmbeddedId; import javax.persistence.Entity; import org.hibernate.Query; import org.hibernate.SessionFactory; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import com.guwenren.bean.QueryResult; import com.guwenren.utils.GenericsUtils; @Transactional public abstract class DaoSupport<T> implements DAO<T> { @SuppressWarnings("unchecked") protected Class<T> entityClass=GenericsUtils.getSuperClassGenricType(this.getClass()); @Resource protected SessionFactory factory; public long getCount() { return (Long)factory.getCurrentSession().createQuery("select count("+ getCountField(this.entityClass) +") from "+ getEntityName(this.entityClass)+ " o").uniqueResult(); } public void clear() { factory.getCurrentSession().clear(); } public void save(T entity) { factory.getCurrentSession().persist(entity); } public void update(T entity) { factory.getCurrentSession().merge(entity); } public void delete(Serializable... serializables) { for(Object id : serializables){ factory.getCurrentSession().delete(factory.getCurrentSession().load(entityClass, (Serializable) id)); } } @SuppressWarnings("unchecked") @Transactional(readOnly=true,propagation=Propagation.NOT_SUPPORTED) public T find(Serializable serializable) { if(serializable==null) throw new RuntimeException(this.entityClass.getName()+ ":传入的实体id不能为空"); return (T) factory.getCurrentSession().get(this.entityClass, serializable);//load } @Transactional(readOnly=true,propagation=Propagation.NOT_SUPPORTED) public QueryResult<T> getScrollData(int firstindex, int maxresult, String wherejpql, Object[] queryParams) { return getScrollData(firstindex,maxresult,wherejpql,queryParams,null); } @Transactional(readOnly=true,propagation=Propagation.NOT_SUPPORTED) public QueryResult<T> getScrollData(int firstindex, int maxresult, LinkedHashMap<String, String> orderby) { return getScrollData(firstindex,maxresult,null,null,orderby); } @Transactional(readOnly=true,propagation=Propagation.NOT_SUPPORTED) public QueryResult<T> getScrollData(int firstindex, int maxresult) { return getScrollData(firstindex,maxresult,null,null,null); } @Transactional(readOnly=true,propagation=Propagation.NOT_SUPPORTED) public QueryResult<T> getScrollData() { return getScrollData(-1,-1); } @SuppressWarnings("unchecked") @Transactional(readOnly=true,propagation=Propagation.NOT_SUPPORTED) public QueryResult<T> getScrollData(int firstindex, int maxresult, String wherejpql, Object[] queryParams, LinkedHashMap<String, String> orderby) { QueryResult<T> qr = new QueryResult<T>(); String entityname = getEntityName(this.entityClass); String wherestr=(wherejpql==null || "".equals(wherejpql.trim())? "": " where "+ wherejpql); String querystr="select o from "+entityname+" o"+wherestr+buildOrderby(orderby); Query query = factory.getCurrentSession().createQuery(querystr); setQueryParams(query, queryParams); if(firstindex!=-1 && maxresult!=-1){ query.setFirstResult(firstindex).setMaxResults(maxresult); } qr.setResultlist(query.list()); if(firstindex!=-1 && maxresult!=-1){ query=factory.getCurrentSession().createQuery("select count(o) from "+entityname+" o"+wherestr); setQueryParams(query, queryParams); qr.setTotalrecord((Long)query.uniqueResult()); } return qr; } /** * 组装where 语句 * @param orderby */ 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(); } /** * 获取实体的名称 * @param <E> * @param clazz 实体类 * @return */ protected static <E> String getEntityName(Class<E> clazz){ String entityname = clazz.getSimpleName(); Entity entity = clazz.getAnnotation(Entity.class); if(entity.name()!=null && !"".equals(entity.name())){ entityname = entity.name(); } return entityname; } /** * 获取统计属性,该方法是为了解决hibernate解析联合主键select count(o) from Xxx o语句BUG而增加, * hibernate对此jpql解析后的sql为select count(field1,field2,...),显示使用count()统计多个字段是错误的 * @param <E> * @param clazz * @return */ protected static <E> String getCountField(Class<E> clazz){ String out = "o"; try { PropertyDescriptor[] propertyDescriptors = Introspector.getBeanInfo(clazz).getPropertyDescriptors(); for(PropertyDescriptor propertydesc : propertyDescriptors){ Method method = propertydesc.getReadMethod(); if(method!=null && method.isAnnotationPresent(EmbeddedId.class)){ PropertyDescriptor[] ps = Introspector.getBeanInfo(propertydesc.getPropertyType()).getPropertyDescriptors(); out = "o."+ propertydesc.getName()+ "." + (!ps[1].getName().equals("class")? ps[1].getName(): ps[0].getName()); break; } } } catch (Exception e) { e.printStackTrace(); } return out; } }