package com.test.dao.base;
import java.beans.PropertyDescriptor;
import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.PropertyUtils;
import org.hibernate.EntityMode;
import org.hibernate.HibernateException;
import org.hibernate.LockMode;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Example;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Projection;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.hibernate.metadata.ClassMetadata;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
@SuppressWarnings("unchecked")
public class BaseDaoImpl<T extends Serializable> extends HibernateDaoSupport implements BaseDao<T> {
private Class<T> persistentClass;
public T save(T entity) {
getHibernateTemplate().save(entity);
return entity;
}
public Object update(Object entity) {
getHibernateTemplate().update(entity);
return entity;
}
public Object saveOrUpdate(Object entity) {
getHibernateTemplate().saveOrUpdate(entity);
return entity;
}
public T merge(T entity) {
return (T) getHibernateTemplate().merge(entity);
}
public void delete(Object entity) {
getHibernateTemplate().delete(entity);
}
public T deleteById(Serializable id) {
Serializable entity = load(id);
getHibernateTemplate().delete(entity);
return (T) entity;
}
public T load(Serializable id) {
return load(id, false);
}
public T get(Serializable id) {
return (T) getHibernateTemplate().get(getPersistentClass(), id);
}
public T load(Serializable id, boolean lock) {
Serializable entity;
if (lock)
entity = (Serializable) getHibernateTemplate().load(getPersistentClass(), id, LockMode.UPGRADE);
else {
entity = (Serializable) getHibernateTemplate().load(getPersistentClass(), id);
}
return (T) entity;
}
public List<T> findAll() {
return getHibernateTemplate().loadAll(getPersistentClass());
}
public List<T> findAll(OrderBy[] orders) {
DetachedCriteria dcrit = DetachedCriteria.forClass(getPersistentClass());
if (orders != null) {
for (OrderBy order : orders) {
dcrit.addOrder(order.getOrder());
}
}
return findByCriteria(dcrit);
}
protected List findByHql(final String hql, final Map<String, Object> paramMap,
final int firstResult, final int maxResult) {
HibernateCallback callback = new HibernateCallback() {
public Object doInHibernate(Session s) throws HibernateException, SQLException {
Query query = s.createQuery(hql);
query.setProperties(paramMap);
query.setFirstResult(firstResult);
query.setMaxResults(maxResult);
return query.list();
}
};
return getHibernateTemplate().executeFind(callback);
}
protected List findByHql(String hql, String param, Object value, int firstResult, int maxResult) {
Map paramMap = new HashMap();
paramMap.put(param, value);
return findByHql(hql, paramMap, firstResult, maxResult);
}
public PaginationSupport findAll(int page, int countPerPage, OrderBy[] orders) {
DetachedCriteria dcrit = DetachedCriteria.forClass(getPersistentClass());
if (orders != null) {
for (OrderBy order : orders) {
dcrit.addOrder(order.getOrder());
}
}
return findByCriteria(dcrit, page, countPerPage);
}
protected PaginationSupport find(Finder find, int page) {
return find(find, page, PaginationSupport.getDefaultCountPerPage());
}
protected PaginationSupport find(Finder find, int page, int countPerPage) {
if (page <= 0) {
page = 1;
}
if (countPerPage <= 0) {
countPerPage = PaginationSupport.getDefaultCountPerPage();
}
return findByFind(find, page, countPerPage);
}
private PaginationSupport findByFind(final Finder find, final int page, final int countPerPage) {
HibernateCallback callback = new HibernateCallback() {
public Object doInHibernate(Session s) throws HibernateException, SQLException {
Query query = s.createQuery(find.getRowCountHql());
query.setProperties(find.getParamMap());
long totalCount = ((Long) query.iterate().next()).longValue();
int queryPage = BaseDaoImpl.this.adjustPage(page, countPerPage, totalCount);
query = s.createQuery(find.getOrigHql());
query.setProperties(find.getParamMap());
query.setFirstResult((queryPage - 1) * countPerPage);
query.setMaxResults(countPerPage);
List list = query.list();
return new PaginationSupport(queryPage, totalCount, countPerPage, list);
}
};
return (PaginationSupport) getHibernateTemplate().execute(callback);
}
@SuppressWarnings("unused")
private void prepareQuery(Query query, List<String> params, List<Object> values) {
for (int i = 0; i < values.size(); ++i)
query.setParameter((String) params.get(i), values.get(i));
}
public List<T> findListByExample(T exampleInstance, boolean matchAnywhere, Condition[] conditions, String[] excludeProperty) {
DetachedCriteria dcrit = getDcritByExample(exampleInstance, matchAnywhere, conditions, excludeProperty);
return getHibernateTemplate().findByCriteria(dcrit);
}
public List<T> findListByExample(T exampleInstance, boolean matchAnywhere,
Condition[] conditions, int firstResult, int maxResult, String[] excludeProperty) {
DetachedCriteria dcrit = getDcritByExample(exampleInstance, matchAnywhere, conditions, excludeProperty);
return getHibernateTemplate().findByCriteria(dcrit, firstResult, maxResult);
}
public PaginationSupport findByExample(T exampleInstance,
boolean matchAnywhere, Condition[] conditions, int page, int countPerPage, String[] excludeProperty) {
DetachedCriteria dcrit = getDcritByExample(exampleInstance, matchAnywhere, conditions, excludeProperty);
return findByCriteria(dcrit, page, countPerPage);
}
private DetachedCriteria getDcritByExample(T bean, boolean matchAnywhere,
Condition[] conditions, String[] excludeProperty) {
Map map = null;
try {
map = describe(bean);
} catch (Exception e) {
throw new RuntimeException(e);
}
Set<Map.Entry> set = map.entrySet();
for (Map.Entry entry : set) {
Object value = entry.getValue();
if ((value == null) || (!(value instanceof String)) || (!((String) value).trim().equals("")))
continue;
try {
BeanUtils.copyProperty(bean, (String) entry.getKey(), null);
} catch (Exception e) {
throw new RuntimeException("属性拷贝错误!");
}
}
//从这里开始
DetachedCriteria dcrit = DetachedCriteria.forClass(getPersistentClass());
Example example = Example.create(bean);
if (matchAnywhere) {
example.enableLike(MatchMode.ANYWHERE);
example.ignoreCase();
}
for(String exclude : excludeProperty){
example.excludeProperty(exclude);
}
dcrit.add(example);
if (conditions != null) {
for(Condition o : conditions){
if (o instanceof OrderBy) {
OrderBy order = (OrderBy) o;
dcrit.addOrder(order.getOrder());
} else if (o instanceof Nullable) {
Nullable isNull = (Nullable) o;
if (isNull.isNull()){
dcrit.add(Restrictions.isNull(isNull.getField()));
} else {
dcrit.add(Restrictions.isNotNull(isNull.getField()));
}
}else {
throw new RuntimeException("orderAndNull类型错误:" + o.getClass().getName());
}
}
}
ClassMetadata cm = getCmd(bean.getClass());
String[] fieldNames = cm.getPropertyNames();
for(String field : fieldNames){
Object o = cm.ge