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