泛型<T>的类型获取

      T.getClass()或者T.class都是非法的,因为T是泛型变量。由于一个类的类型是什么,是在编译期处理的,故不能在运行时直接在Base里得到T的实际类型。获取T应该根据如下方法:

/**
 *@author zhangwenchao
 *@version   
 * 可以在service层直接调用,也可以在DAO层扩展调用
 */
public class BaseDaoImpl<T, PK extends Serializable> implements BaseDao<T, PK>{

     
     private Class<T> persistentClass;


    
     /**
      * 用于Dao层子类使用的构造函数. 通过子类的泛型定义取得对象类型
      */

     @SuppressWarnings("unchecked")
     public BaseDaoImpl(){
	//返回表示此 Class 所表示的实体(类、接口、基本类型或 void)的超类的 Class。
	this.persistentClass=(Class<T>)getSuperClassGenricType(getClass(), 0);
     }


    /**
     * 通过反射, 获得定义Class时声明的父类的泛型参数的类型. 如无法找到, 返回Object.class.
     * 
     *@param clazz
     *            clazz The class to introspect
     * @param index
     *            the Index of the generic ddeclaration,start from 0.
     * @return the index generic declaration, or Object.class if cannot be
     *         determined
     */
    @SuppressWarnings("unchecked")
    public static Class<Object> getSuperClassGenricType(final Class clazz, final int index) {
    	
    	//返回表示此 Class 所表示的实体(类、接口、基本类型或 void)的直接超类的 Type。
        Type genType = clazz.getGenericSuperclass();

        if (!(genType instanceof ParameterizedType)) {
           return Object.class;
        }
        //返回表示此类型实际类型参数的 Type 对象的数组。
        Type[] params = ((ParameterizedType) genType).getActualTypeArguments();

        if (index >= params.length || index < 0) {
                     return Object.class;
        }
        if (!(params[index] instanceof Class)) {
              return Object.class;
        }

        return (Class) params[index];
    }

}


 

具体再Hibernate使用如下:

1、IBaseDao.java

package org.nercita.core.orm;

import java.io.Serializable;
import java.util.List;
import java.util.Map;

import org.nercita.core.search.Search;

/**
 * 针对单个实体对象的操作定义.不依赖于具体ORM实现方案.
 * @author zhangwenchao
 * @param <T> 实体
 * @param <PK> 主键类型
 * 
 */

public interface IBaseDao<T, PK extends Serializable> {
	
	/**
	 * 根据Id查询实体
	 * @param id
	 * @return 实体对象
	 */
	T findById(PK id);
	
	
	/**
	 * 根据Id查询实体
	 * @param id
	 * @return 实体对象
	 */
	T getById(PK id);
	
	
	/**
	 * 根据id查询实体,并加锁
	 * @param id 
	 * @return 实体对象
	 */
	public T findByIdForLock(PK id);
	
	/**
	 * 根据id查询实体,并加锁
	 * @param id 
	 * @return 实体对象
	 */
	public T getByIdForLock(final PK id);
	
	
	/**
	 * 保存实体
	 * @param entity 实体对象
	 */
	void save(T entity);
	
	
	/**
	 * 更新实体
	 * @param entity 实体对象
	 */
	void update(T entity);
	
	
	/**
	 * 更新实体
	 * @param entity 实体对象
	 */
	void saveOrUpdate(T entity);
	
	
	/**
	 * 删除实体
	 * @param entity 实体对象
	 */
	void delete(T entity);
		
	
	/**
	 * 根据hql执行语句,用于批量更新删除
	 * @param queryString hql语句
	 * @param values 可变参数
	 * @return 影响的个数
	 */
	public int execute(String queryString, Object... values);
	
	
	/**
	 * 根据Id删除实体
	 * @param id 
	 */
	void deleteById(PK id);
	
	
	/**
	 * 查询所有实体
	 * @return List 查询结果集
	 */
	List<T> findAll();
	
	
	/**
	 * 根据条件模糊查询所有实体
	 * @param queryName 要查询的列名
	 * @param queryValue 要查询的值
	 * @return List 查询结果集
	 */
	List<T> findAllLike(String queryName, Object queryValue);
	
	
	/**
	 * 根据条件精确查询所有实体
	 * @param queryName 要查询的列名
	 * @param queryValue 要查询的值
	 * @return List 查询结果集
	 */
	List<T> findAllEq(String queryName, Object queryValue);
	
	
	/**
	 * 分页查询所有实体
	 * @param page 分页条件
	 * @return Page 分页查询结果,附带结果列表及所有查询时的参数.<br>
	 * 				可通过page.getResult()获取.
	 */
	Page<T> findPage(Page<T> page);
	
	
	
	/**
	 * 按属性查找唯一对象.
	 * @param propertyName 要查询的列名
	 * @param value 要查询的值(精确查询)
	 * @return 实体对象
	 */
	public T findUniqueByProperty(String propertyName, Object value);
	
	
	
	/**
	 * 根据单个查询条件分页(精确查询)
	 * @param page 分页参数
	 * @param queryName 要查询的列名
	 * @param queryValue 要查询的值
	 * @return Page 分页查询结果.
	 */
	public Page<T> findPageByPropertyExact(Page<T> page, String queryName, Object queryValue);
	
	
	
	/**
	 * 根据单个查询条件分页(模糊查询)
	 * @param page 分页参数
	 * @param queryName 要查询的列名
	 * @param queryValue 要查询的值
	 * @return Page 分页查询结果.
	 */
	public Page<T> findPageByPropertyLike(Page<T> page, String queryName, Object queryValue);
	
	
	
	/**
	 * 根据查询条件分页查询(模糊查询)
	 * @param page 分页参数
	 * @param entity 查询实体,设置了要查询的条件
	 * @return Page 分页查询结果.
	 */
	public Page<T> findPageByQuerysBlur(Page<T> page, T entity);
	
	
	
	/**
	 * 根据查询条件分页查询(精确查询)
	 * @param page 分页参数
	 * @param entity 查询实体,设置了要查询的条件
	 * @return Page 分页查询结果.
	 */
	public Page<T> findPageByQuerysExact(Page<T> page, T entity);
	
	
	
	/**
	 * 根据查询条件分页查询(模糊查询)
	 * @param page 分页参数
	 * @param queryMap 查询条件,在map中以键、值对保存
	 * @return Page 分页查询结果.
	 */
	
	@SuppressWarnings("rawtypes")
	public Page<T> findPageByMap(Page<T> page, Map queryMap);
	
	
	
	/**
	 * 根据查询构建器查询所有记录
	 * @param search 查询构建器
	 * @return List
	 */
	public List<T> search(Search search);
	
	
	
	/**
	 * 根据查询构建器查询Page
	 * @param page 分页参数
	 * @param search 查询构建器
	 * @return Page
	 */
	public Page<T> search(Page<T> page, Search search);
	
}


2、HibernateGenericDao.java

package org.nercita.core.orm.hibernate;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.annotation.Resource;
import javax.persistence.ManyToOne;
import javax.persistence.OneToOne;

import org.apache.commons.lang.StringEscapeUtils;
import org.hibernate.Criteria;
import org.hibernate.Hibernate;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.CriteriaSpecification;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Projection;
import org.hibernate.criterion.Projections;
import org.hibernate.hql.internal.ast.QueryTranslatorImpl;
import org.hibernate.internal.CriteriaImpl;
import org.hibernate.transform.ResultTransformer;

/**
 * Hibernate DAO 操作工具类, 封装了基本操作.
 
 * @author zhangwenchao
 */
public class HibernateGenericDao {
	
	/**
	 * DAO所管理的Entity类型.
	 */
	@SuppressWarnings("rawtypes")
	protected Class entityClass;

	@Resource(name = "sessionFactory")
	protected SessionFactory sessionFactory;

	/**
	 * 获取当前session
	 * @return Session
	 */
	public Session getSession() {
		return sessionFactory.getCurrentSession();
	}
	
	/**
	 * 获取当前sessionFactory
	 * @return sessionFactory
	 */
	public SessionFactory getSessionFactory() {
		return sessionFactory;
	}
	
	@SuppressWarnings("rawtypes")
	public void setEntityClass(Class entityClass){
		this.entityClass = entityClass;
	}
	
	/**
	 * 刷新session
	 */
	public void flush() {
        getSession().flush();
    }

	/**
	 * 清空session
	 */
    public void clear() {
        getSession().clear();
    }
    
    
    /**
     * 根据sql创建Query
     * @param queryString sql语句, 参数必须用"?"设置
     * @param values 可变参数, 对应查询语句里的" ? "
     * @return Query Query对象
     */
    public Query createSqlQuery(String queryString, Object... values) {
		Query queryObject = getSession().createSQLQuery(queryString);
		if (values != null) {
			for (int i = 0; i < values.length; i++) {
				queryObject.setParameter(i, values[i]);
			}
		}
		return queryObject;
	}
	
	
	/**
	 * 根据查询函数与参数列表创建Query对象,后续可进行更多处理.<br>
	 * 对于需要first,max,fetchsize,cache,cacheRegion等诸多设置的函数,可以在返回Query后自行设置.
	 * 
	 * @param queryString HQL查询语句, 参数必须用"?"设置
	 * @param values 可变参数, 对应查询语句里的" ? "
	 * @return Query Query对象
	 */
	public Query createQuery(String queryString, Object... values) {
		Query queryObject = getSession().createQuery(queryString);
		if (values != null) {
			for (int i = 0; i < values.length; i++) {
				queryObject.setParameter(i, values[i]);
			}
		}
		return queryObject;
	}
	

	/**
	 * 根据Criterion条件创建Criteria,后续可进行更多处理.
	 * @param criterions 可变的Restrictions条件列表, 封装了查询条件
	 * @return Criteria Criteria对象
	 */
	public Criteria createCriteria(Criterion... criterions) {
		Criteria criteria = getSession().createCriteria(entityClass);
		Map<String, String> aliasMap = new HashMap<String, String>();
		for (Criterion c : criterions) {
			String propertyName = null;
			try {
				propertyName = getFieldValue(c, "propertyName").toString();
				if (propertyName!=null) {
					String[] paramStrs = propertyName.split("\\.");
					if(paramStrs.length > 1){
						String alias = paramStrs[0];
						Field f  = entityClass.getDeclaredField(alias);
						if(isRelatingObject(f)){
							String param = paramStrs[1];
							String identifier = getIdentifierName(f.getType());
							if(!identifier.equals(param)){
								if(criteria instanceof CriteriaImpl){
									aliasMap.put(alias, alias);
								}
							}
						}
					}
				}
			} catch (NoSuchFieldException e) {
				//没有propertyName属性,直接跳出
			}
			criteria.add(c);
		}
		Iterator<String> iterator = aliasMap.values().iterator();
		while (iterator.hasNext()) {
			String alias = iterator.next();
			criteria.createAlias(alias, alias);
		}
		return criteria;
	}
	
	
	/**
	 * 根据Criterion条件创建Criteria,后续可进行更多处理.
	 * @param criterions 可变的Restrictions条件列表, 封装了查询条件
	 * @return Criteria Criteria对象
	 */
	public Criteria createCriteria(List<Criterion> criterions) {
		Criteria criteria = getSession().createCriteria(entityClass);
		Map<String, String> aliasMap = new HashMap<String, String>();
		for (Criterion c : criterions) {
			String propertyName = null;
			try {
				propertyName = getFieldValue(c, "propertyName").toString();
				if (propertyName!=null) {
					String[] paramStrs = propertyName.split("\\.");
					if(paramStrs.length > 1){
						String alias = paramStrs[0];
						Field f  = entityClass.getDeclaredField(alias);
						if(isRelatingObject(f)){
							String param = paramStrs[1];
							String identifier = getIdentifierName(f.getType());
							if(!identifier.equals(param)){
								if(criteria instanceof CriteriaImpl){
									aliasMap.put(alias, alias);
								}
							}
						}
					}
				}	
			} catch (NoSuchFieldException e) {
				//没有propertyName属性,直接跳出
			}			
			criteria.add(c);
		}
		Iterator<String> iterator = aliasMap.values().iterator();
		while (iterator.hasNext()) {
			String alias = iterator.next();
			criteria.createAlias(alias, alias);
		}
		return criteria;
	}
						
	
	/**
	 * 按HQL查询对象列表.
	 * @param hql hql语句, 参数必须用"?"设置
	 * @param values 可变参数, 对应查询语句里的" ? "
	 * @return List 查询出的对象类表
	 */
	@SuppressWarnings("rawtypes")
	public List findByHql(String hql, Object... values) {
		return createQuery(hql, values).list();
	}
	
	
	/**
	 * 按Criterion查询对象列表.
	 * @param criterion 数量可变的Criterion.
	 * @return List 查询出的对象类表
	 */
	@SuppressWarnings("rawtypes")
	public List findByCriteria(Criterion... criterion) {
		return createCriteria(criterion).list();
	}
	
	
	
	
	/**
	 * 按HQL查询唯一对象.
	 * @param hql HQL语句, 参数必须用"?"设置
	 * @param values 可变参数, 对应查询语句里的" ? "
	 * @return Object 查询出的唯一对象
	 */
	public Object findUnique(String hql, Object... values) {
		return createQuery(hql, values).uniqueResult();
	}
	
	
	/**
	 * 按Criteria查询唯一对象.
	 * @param criterion 数量可变的Criterion.
	 * @return Object 查询出的唯一对象
	 */
	public Object findUnique(Criterion... criterion) {
		return createCriteria(criterion).uniqueResult();
	}
	

	/**
	 * 按HQL查询Intger类形结果,不能用于count查询,count查询可使用findUniqueLong.  
	 * @param hql HQL语句, 参数必须用"?"设置
	 * @param values 可变参数, 对应查询语句里的" ? "
	 */
	public Integer findUniqueInt(String hql, Object... values) {
		return (Integer) findUnique(hql, values);
	}
	

	/**
	 * 按HQL查询Long类型结果,可用于count查询. 	 
	 * @param hql HQL语句, 参数必须用"?"设置
	 * @param values 可变参数, 对应查询语句里的" ? "
	 */
	public Long findUniqueLong(String hql, Object... values) {
		return (Long) findUnique(hql, values);
	}
	
	
	/**
	 * 初始化对象.
	 * 使用load()方法得到的仅是对象Proxy后, 在传到View层前需要进行初始化.
	 * initObject(user) ,初始化User的直接属性,但不会初始化延迟加载的关联集合和属性.
	 * initObject(user.getRoles()),初始化User的直接属性和关联集合.
	 * initObject(user.getDescription()),初始化User的直接属性和延迟加载的Description属性.
	 */
	public void initObject(Object object) {
		Hibernate.initialize(object);
	}

	/**
	 * 批量初始化对象.
	 * @see #initObject(Object)
	 */
	@SuppressWarnings("rawtypes")
	public void initObjects(List list) {
		for (Object object : list) {
			Hibernate.initialize(object);
		}
	}

	/**
	 * 通过Set将不唯一的对象列表唯一化.
	 * 主要用于HQL/Criteria预加载关联集合形成重复记录,又不方便使用distinct查询语句时.
	 */
	public <X> List<X> distinct(List<X> list) {
		Set<X> set = new LinkedHashSet<X>(list);
		return new ArrayList<X>(set);
	}

	public Query distinct(Query query) {
		query.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);
		return query;
	}

	public Criteria distinct(Criteria c) {
		c.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);
		return c;

	}
	
	/**
     * 获取当前实体的主键名称
     * @param entityClass 实体类
     * @return 主键字段名
     */
    public String getIdentifierName(){
    	return getSessionFactory().getClassMetadata(entityClass).getIdentifierPropertyName();
    }
    
    /**
     * 获取给定实体的主键名称
     * @param entityClass 实体类
     * @return 主键字段名
     */
    @SuppressWarnings("rawtypes")
	public String getIdentifierName(Class entityClass){
    	return getSessionFactory().getClassMetadata(entityClass).getIdentifierPropertyName();
    }
	
	
	/**
	 * 去除hql的select 子句,未考虑union的情况,用于pagedQuery.
	 * @param hql HQL语句,只限于单实体查询
	 */
	public String removeSelect(String hql) {
		int beginPos = hql.toLowerCase().indexOf("from");
		return hql.substring(beginPos);
	}
	
	

	/**
	 * 去除hql的orderby 子句,用于pagedQuery.
	 * @param hql HQL语句
	 */
	public String removeOrders(String hql) {
		Pattern p = Pattern.compile("order\\s*by[\\w|\\W|\\s|\\S]*", Pattern.CASE_INSENSITIVE);
		Matcher m = p.matcher(hql);
		StringBuffer sb = new StringBuffer();
		while (m.find()) {
			m.appendReplacement(sb, "");
		}
		m.appendTail(sb);
		return sb.toString();
	}
	
	
	
	/**
	 * 过滤sql语句,防止注入
	 * @param hql SQL语句
	 */
	public String replaceInject(String hql) {
		return StringEscapeUtils.escapeSql(hql);
	}
	
	
	
	/**
	 * 将hql查询语句转化成count(*)统计结果集语句
	 * @param hql HQL语句
	 */
	public String replaceCountHql(String hql) {
		return "select count(*) " + removeOrders(removeSelect(hql));
	}
	
	
	
	/**
	 * 将hql转化为count(*) sql语句
	 * @param originalHql hql语句
	 * @return sql语句
	 */
	public String getCountSql(String originalHql) { 
		QueryTranslatorImpl queryTranslator = new QueryTranslatorImpl(originalHql, originalHql, 
		Collections.EMPTY_MAP, (org.hibernate.engine.spi.SessionFactoryImplementor)getSessionFactory()); 
		queryTranslator.compile(Collections.EMPTY_MAP, false); 
		return "select count(*) from (" + queryTranslator.getSQLString() + ") tmp_count_t"; 
	}
	
	

	/**
	 * 通过count查询获得本次查询所能获得的对象总数.
	 * @param c Criteria 查询条件
	 * @return int 结果总数
	 */
	@SuppressWarnings({ "unchecked", "rawtypes" })
	public long getCountByCriteria(Criteria c) {
		CriteriaImpl impl = (CriteriaImpl) c;

		// 先把Projection、ResultTransformer、OrderBy取出来,清空三者后再执行Count操作
		Projection projection = impl.getProjection();
		ResultTransformer transformer = impl.getResultTransformer();

		List<CriteriaImpl.OrderEntry> orderEntries = null;
		try {
			orderEntries = (List) getFieldValue(impl, "orderEntries");
			setFieldValue(impl, "orderEntries", new ArrayList());
		} catch (NoSuchFieldException e) {
			e.printStackTrace();
		}	

		// 执行Count查询
		long totalCount = (Long) c.setProjection(Projections.rowCount()).uniqueResult();
		if (totalCount < 0)
			return -1;

		// 将之前的Projection和OrderBy条件重新设回去
		c.setProjection(projection);

		if (projection == null) {
			c.setResultTransformer(CriteriaSpecification.ROOT_ENTITY);
		}
		if (transformer != null) {
			c.setResultTransformer(transformer);
		}

		try {
			setFieldValue(impl, "orderEntries", orderEntries);
		} catch (NoSuchFieldException e) {
			e.printStackTrace();
		}
		return totalCount;
	}
	
	
	/**
	 * 直接读取对象属性值,无视private/protected修饰符,不经过getter函数.
	 * @throws NoSuchFieldException 
	 */
	protected Object getFieldValue(Object object, String fieldName) throws NoSuchFieldException {
		Field field = getDeclaredField(object, fieldName);
		if (!field.isAccessible()) {
			field.setAccessible(true);
		}
		Object result = null;
		try {
			result = field.get(object);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}
	
	
	
	/**
	 * 循环向上转型,获取对象的DeclaredField.
	 * @throws NoSuchFieldException 
	 */
	protected Field getDeclaredField(Object object, String fieldName) throws NoSuchFieldException {
		return getDeclaredField(object.getClass(), fieldName);
	}
	
	
	
	/**
	 * 循环向上转型,获取类的DeclaredField.
	 */
	@SuppressWarnings("rawtypes")
	protected Field getDeclaredField(Class clazz, String fieldName) throws NoSuchFieldException {
		for (Class superClass = clazz; superClass != Object.class; superClass = superClass.getSuperclass()) {
			try {
				return superClass.getDeclaredField(fieldName);
			} catch (NoSuchFieldException e) {
				// Field不在当前类定义,继续向上转型
			}
		}
		throw new NoSuchFieldException("No such field: " + clazz.getName() + '.' + fieldName);
	}
	
	
	
	/**
	 * 直接设置对象属性值,无视private/protected修饰符,不经过setter函数.
	 * @throws NoSuchFieldException 
	 */
	protected void setFieldValue(Object object, String fieldName, Object value) throws NoSuchFieldException {
		Field field = getDeclaredField(object, fieldName);
		if (!field.isAccessible()) {
			field.setAccessible(true);
		}
		try {
			field.set(object, value);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 判断此字段是否是多对一或者一对一关联
	 * @param field 字段名称
	 * @return “是”则返回true
	 */
	protected boolean isRelatingObject(Field field){
		return field.isAnnotationPresent(ManyToOne.class) || field.isAnnotationPresent(OneToOne.class);
	}
	
}


 

3、HibernateBaseDao.java

package org.nercita.core.orm.hibernate;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.hibernate.Criteria;
import org.hibernate.LockOptions;
import org.hibernate.Query;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Example;
import org.hibernate.criterion.Junction;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.nercita.core.orm.IBaseDao;
import org.nercita.core.orm.Page;
import org.nercita.core.search.Filter;
import org.nercita.core.search.Search;
import org.nercita.core.search.Sort;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.Assert;

/**
 * 负责为单个Entity对象提供CRUD操作的Hibernate DAO基类.<p/>
 * 
 * 子类只要在类定义时指定所管理Entity的Class, 即拥有对单个Entity对象的CRUD操作.
 * 
 * @author zhangwenchao
 
 * @param <T>  DAO操作的对象类型
 * @param <PK>  主键类型
 
 * @see org.nercita.core.orm.hibernate.HibernateGenericDao
 */
@SuppressWarnings("unchecked")
public class HibernateBaseDao<T, PK extends Serializable> extends
		HibernateGenericDao implements IBaseDao<T, PK> {

	protected Logger logger = LoggerFactory.getLogger(getClass());

	public HibernateBaseDao() {
		if(this.entityClass == null){
			this.entityClass = (Class<T>) ((ParameterizedType) getClass()
					.getGenericSuperclass()).getActualTypeArguments()[0];
		}
	}

	protected Class<T> getEntityClass() {
		return entityClass;
	}
	
	
	public T findById(final PK id) {
		Assert.notNull(id, "id不能为空");
	    return (T) getSession().load(getEntityClass(), id);
		
		
	}
	
	public T getById(final PK id) {
		Assert.notNull(id, "id不能为空");
		return (T) getSession().get(getEntityClass(), id);
		
	}
	

	public T findByIdForLock(final PK id) {
		Assert.notNull(id, "id不能为空");
		return (T) getSession().load(getEntityClass(), id, LockOptions.UPGRADE);
	}
	
	public T getByIdForLock(final PK id) {
		Assert.notNull(id, "id不能为空");
		return (T) getSession().get(getEntityClass(), id, LockOptions.UPGRADE);
	}


	public void save(final T entity) {
		Assert.notNull(entity, "entity不能为空");
		getSession().save(entity);
		logger.info("save entity: {}", entity);
	}
	
	/**
	 * 保存实体列表
	 * @param entity 实体列表对象
	 */
	public void save(final List<T> entities){
		Assert.notNull(entities, "entities不能为空");
		for(int i=0;i<entities.size();i++)
	     getSession().save(entities.get(i));
		logger.info("save entities: {}", entities);
	}
	

	public void update(final T entity) {
		Assert.notNull(entity, "entity不能为空");
		getSession().update(entity);
		logger.info("update entity: {}", entity);
	}
	
	public void saveOrUpdate(final T entity) {
		Assert.notNull(entity, "entity不能为空");
		getSession().saveOrUpdate(entity);
		logger.debug("save entity: {}", entity);
	}

	public void merge(final T entity) {
		Assert.notNull(entity, "entity不能为空");
		getSession().merge(entity);
		logger.debug("save entity: {}", entity);
	}
	
	public void delete(final T entity) {
		Assert.notNull(entity, "entity不能为空");
		getSession().delete(entity);
		logger.info("delete entity: {}", entity);
	}
	
	/**
	 * 批量删除实体列表
	 * @param entity 实体对象列表
	 */
	public void delete(List<T> entities){
		Assert.notNull(entities, "entity不能为空");
		for(int i=0;i<entities.size();i++)
		getSession().delete(entities.get(i));
		logger.info("delete entities: {}", entities);
	}
	

	public void deleteById(final PK id) {
		Assert.notNull(id, "id不能为空");
		delete(findById(id));
		logger.info("delete entity {}, id is {}", entityClass.getSimpleName() , id);
	}
	

	public int execute(final String queryString, final Object... values){
		Assert.hasText(queryString, "queryString不能为空");
		return createQuery(queryString, values).executeUpdate();	
	}
		
	
	public List<T> findAll() {
		return findByCriteria();
	}
	
	public List<T> findAllLike(String queryName, Object queryValue) {
		Criterion criterion = Restrictions.like(queryName, queryValue);
		return findAll(criterion);
	}
	
	public List<T> findAllEq(String queryName, Object queryValue) {
		Criterion criterion = Restrictions.eq(queryName, queryValue);
		return findAll(criterion);
	}
	
	
	public List<T> findAll(Criterion... criterion) {
		return findByCriteria(criterion);
	}
	
	
	public Page<T> findPage(final Page<T> page) {
		Assert.notNull(page, "page不能为空");
		return findPageByCriteria(page);
	}
	
	
	public T findUniqueByProperty(final String propertyName, final Object value) {
		Assert.hasText(propertyName, "propertyName不能为空");
		return (T) createCriteria(Restrictions.eq(propertyName, value)).uniqueResult();
	}
	
	
	/**
	 * 按HQL分页查询.
	 * 暂不支持自动获取总结果数,需用户另行执行查询.
	 * @param page 分页参数.包括pageSize 和firstResult.
	 * @param hql HQL查询语句, 参数必须用“?”设置.
	 * @param values 数量可变的参数, 对应查询语句里的“?”.
	 * @return 分页查询结果,附带结果列表及所有查询时的参数.
	 */
	public Page<T> findPageByHql(Page<T> page, String hql, Object... values) {
		Assert.notNull(page, "page不能为空");
		Assert.hasText(hql, "hql不能为空");
		long count = findCountByHql(hql, values);
		if(count>-1)
			page.setTotalCount((int)count);
		Query q = createQuery(hql, values);
		q.setFirstResult(page.getFirst());
		q.setMaxResults(page.getPageSize());
	
		page.setResult(q.list());
		return page;
	}
	
	
	
	public long findCountByHql(String hql, Object... values) {
		if(hql.toLowerCase().indexOf("group by")>0 || hql.toLowerCase().indexOf(" distinct ")>0){
			String sql = getCountSql(removeOrders(hql));
			Query query = createSqlQuery(sql, values);
			return Long.parseLong(query.uniqueResult().toString());
		}else {
			return findUniqueLong(replaceCountHql(hql), values);
		}
	}
	
	
	/**
	 * 根据查询条件分页查询
	 * @param page 分页参数
	 * @param entity 查询实体,设置了要查询的条件
	 * @param matchMode 查询的精确类型<br>
	 * MatchMode: EXACT-精确查询,ANYWHERE-模糊查询,START-开头匹配,END-结尾匹配
	 * @param criterion 数量可变的Criterion.
	 * @return Page 分页查询结果.
	 */
	public Page<T> findPageByQuerys(Page<T> page, T entity, MatchMode matchMode, Criterion... criterion) {
		Assert.notNull(page, "page不能为空");
		Criteria c = createCriteria(criterion);
		if(entity!=null){
			Example example = Example.create(entity);
			example.enableLike(matchMode);		//设置查询类型	
			c.add(example);
		}
		// 获取根据条件分页查询的总行数 
		page.setTotalCount(getCountByCriteria(c));
		c.setFirstResult(page.getFirst());
		c.setMaxResults(page.getPageSize());
		if (page.isOrderBySetted()) {
			String[] orderByArray = StringUtils.split(page.getOrderBy(), ',');
			String[] orderArray = StringUtils.split(page.getOrder(), ',');
			Assert.isTrue(orderByArray.length == orderArray.length, "分页多重排序参数中,排序字段与排序方向的个数不相等");

			for (int i = 0; i < orderByArray.length; i++) {
				if (Page.ASC.equals(orderArray[i])) {
					c.addOrder(Order.asc(orderByArray[i]));
				} else {
					c.addOrder(Order.desc(orderByArray[i]));
				}
			}
		}
		page.setResult(c.list());
		return page;
	}

	/**
	 * 根据查询条件分页查询
	 * @param page 分页参数
	 * @param entity 查询实体,设置了要查询的条件
	 * @param matchMode 查询的精确类型<br>
	 * MatchMode: EXACT-精确查询,ANYWHERE-模糊查询,START-开头匹配,END-结尾匹配
	 * @param criterion  Criterion List.
	 * @return Page 分页查询结果.
	 */
	public Page<T> findPageByQuerys(Page<T> page, T entity, MatchMode matchMode, List<Criterion> criterion) {
		Assert.notNull(page, "page不能为空");
		Criteria c = createCriteria(criterion);
		if(entity!=null){
			Example example = Example.create(entity);
			example.enableLike(matchMode);		//设置查询类型	
			c.add(example);
		}
		page.setTotalCount(getCountByCriteria(c));
		c.setFirstResult(page.getFirst());
		c.setMaxResults(page.getPageSize());
		if (page.isOrderBySetted()) {
			String[] orderByArray = StringUtils.split(page.getOrderBy(), ',');
			String[] orderArray = StringUtils.split(page.getOrder(), ',');

			Assert.isTrue(orderByArray.length == orderArray.length, "分页多重排序参数中,排序字段与排序方向的个数不相等");

			for (int i = 0; i < orderByArray.length; i++) {
				if (Page.ASC.equals(orderArray[i])) {
					c.addOrder(Order.asc(orderByArray[i]));
				} else {
					c.addOrder(Order.desc(orderByArray[i]));
				}
			}
		}
		page.setResult(c.list());
		return page;
	}
	
	
	
	/**
	 * 按Criterion分页查询.
	 * @param page 分页参数
	 * @param criterion 数量可变的Criterion.
	 * @return 分页查询结果.附带结果列表及所有查询时的参数.
	 */
	public Page<T> findPageByCriteria(Page<T> page, Criterion... criterion) {
		return findPageByQuerys(page, null, null, criterion);
	}
	
	
	/**
	 * 按Criterion分页查询.
	 * @param page 分页参数
	 * @param criterion Criterion List.
	 * @return 分页查询结果.附带结果列表及所有查询时的参数.
	 */
	public Page<T> findPageByCriteria(Page<T> page, List<Criterion> criterion) {
		return findPageByQuerys(page, null, null, criterion);
	}
	
	
	/**
	 * 按Criterion查询结果数.
	 * @param criterion 数量可变的Criterion.
	 * @return 查询结果
	 */
	public long findCountByCriteria(Criterion... criterion) {
		Criteria c = createCriteria(criterion);
		return getCountByCriteria(c);
	}
	
	
	/**
	 * 根据查询条件分页查询
	 * @param page 分页参数
	 * @param entity 查询实体,设置了要查询的条件
	 * @param matchMode 查询的精确类型<br>
	 * MatchMode: EXACT-精确查询,ANYWHERE-模糊查询,START-开头匹配,END-结尾匹配
	 * @return Page 分页查询结果.
	 */
	public Page<T> findPageByQueryMatch(Page<T> page, T entity, MatchMode matchMode) {
		return findPageByQuerys(page, entity, matchMode);
	}
	

	public Page<T> findPageByQuerysBlur(Page<T> page, T entity) {
		return findPageByQuerys(page, entity, MatchMode.ANYWHERE);
	}
	
	
	public Page<T> findPageByQuerysExact(Page<T> page, T entity) {
		return findPageByQuerys(page, entity, MatchMode.EXACT);
	}
	
	
	
	public Page<T> findPageByPropertyExact(Page<T> page, String queryName, Object queryValue) {
		Criterion criterion = Restrictions.eq(queryName, queryValue);
		return findPageByCriteria(page, criterion);
	}
	
	
	public Page<T> findPageByPropertyLike(Page<T> page, String queryName, Object queryValue) {
		Criterion criterion = Restrictions.like(queryName, "%"+queryValue+"%");
		return findPageByCriteria(page, criterion);
	}
	
	
	
	@SuppressWarnings("rawtypes")
	public Page<T> findPageByMap(Page<T> page, Map queryMap) {
		Assert.notNull(page, "page不能为空");
		Assert.notNull(queryMap, "queryMap不能为空");
		StringBuffer hql = new StringBuffer("from ");
		hql.append(getEntityClass().getName()).append(" where 1=1 ");
		Iterator it = queryMap.keySet().iterator();   
        while (it.hasNext()) { 
            Object key = it.next();
            hql.append(" and ").append(key.toString()).append(" like '%").append(replaceInject(String.valueOf(queryMap.get(key)))).append("%'");
        }
		return findPageByHql(page, hql.toString());
	}
	
	
	/**
	 * 根据查询构建器查询所有记录
	 * @param search 查询构建器
	 * @return List
	 */
	public List<T> search(Search search) {
		Assert.notNull(search, "search不能为空");
		List<Criterion> criterionList = new ArrayList<Criterion>();
		List<Filter> filters = search.getFilters();
		for(Filter filter : filters){
			if(!filter.getValue().equals("") && filter.getValue()!=null)
			criterionList.add(filter.isSimpleFilter() ? 
					buildCriterionBySimFilter(filter) : buildCriterionByConnFilter(filter));
		}
		Criteria c = createCriteria(criterionList);
		List<Sort> sorts = search.getSorts();
		for(Sort sort : sorts){
			if(sort.getOrder().equals(Sort.ASC)){
				c.addOrder(Order.asc(sort.getProperty()));
			}
			if(sort.getOrder().equals(Sort.DESC)){
				c.addOrder(Order.desc(sort.getProperty()));
			}
		}
		return c.list();
	}
	
	
	/**
	 * 根据查询构建器查询Page
	 * @param page 分页参数
	 * @param search 查询构建器
	 * @return Page
	 */
	public Page<T> search(Page<T> page, Search search) {
		Assert.notNull(search, "search不能为空");
		List<Criterion> criterionList = new ArrayList<Criterion>();
		List<Filter> filters = search.getFilters();
		for(Filter filter : filters){
			if(!"".equals(filter.getValue()) && null != filter.getValue())
			criterionList.add(filter.isSimpleFilter() ? 
					buildCriterionBySimFilter(filter) : buildCriterionByConnFilter(filter));
		}
		Criteria c = createCriteria(criterionList);
		page.setTotalCount(getCountByCriteria(c));
		c.setFirstResult(page.getFirst());
		c.setMaxResults(page.getPageSize());
		List<Sort> sorts = search.getSorts();
		for(Sort sort : sorts){
			if(sort.getOrder().equals(Sort.ASC)){
				c.addOrder(Order.asc(sort.getProperty()));
			}
			if(sort.getOrder().equals(Sort.DESC)){
				c.addOrder(Order.desc(sort.getProperty()));
			}
		}
		page.setResult(c.list());
		return page;
	}
	
	
	
	/**
	 * 根据Filter构造过滤条件
	 */
	public Criterion buildCriterionBySimFilter(Filter filter){
		String propertyName = filter.getProperty();
		Object value = filter.getValue();
		int operator = filter.getOperator();
		Criterion criterion = null;
		switch (operator) {
		case Filter.OP_EMPTY:
			criterion = Restrictions.isEmpty(propertyName);
			break;
		case Filter.OP_EQUAL:
			criterion = Restrictions.eq(propertyName, value);
			break;
		case Filter.OP_GREATER_OR_EQUAL:
			criterion = Restrictions.ge(propertyName, value);
			break;
		case Filter.OP_GREATER_THAN:
			criterion = Restrictions.gt(propertyName, value);
			break;
		case Filter.OP_ILIKE:
			criterion = Restrictions.ilike(propertyName, "%"+value+"%");
			break;
		case Filter.OP_IN:
			if(value instanceof Object[])
				criterion = Restrictions.in(propertyName, (Object[])value);
			if(value instanceof Collection<?>)
				criterion = Restrictions.in(propertyName, (Collection<?>)value);
			break;
		case Filter.OP_LESS_OR_EQUAL:
			criterion = Restrictions.le(propertyName, value);
			break;
		case Filter.OP_LESS_THAN:
			criterion = Restrictions.lt(propertyName, value);
			break;
		case Filter.OP_LIKE:
			criterion = Restrictions.like(propertyName, "%"+value+"%");
			break;
		case Filter.OP_NOT_EMPTY:
			criterion = Restrictions.isNotEmpty(propertyName);
			break;
		case Filter.OP_NOT_EQUAL:
			criterion = Restrictions.ne(propertyName, value);
			break;
		case Filter.OP_NOT_IN:
			if(value instanceof Object[])
				criterion = Restrictions.in(propertyName, (Object[])value);
			if(value instanceof Collection<?>)
				criterion = Restrictions.in(propertyName, (Collection<?>)value);
			criterion = Restrictions.not(criterion);
			break;
		case Filter.OP_NOT_NULL:
			criterion = Restrictions.isNotNull(propertyName);
			break;
		case Filter.OP_NULL:
			criterion = Restrictions.isNull(propertyName);
			break;
		case Filter.OP_NOT:
			Filter filterNot = (Filter) filter.getValue();
			criterion = Restrictions.not(filterNot.isSimpleFilter() ?
					buildCriterionBySimFilter(filterNot) : buildCriterionByConnFilter(filterNot));
			break;
		}
		return criterion;
	}
	
	/**
	 * 构造连接过滤条件
	 */
	public Criterion buildCriterionByConnFilter(Filter filter){
		Criterion criterion = null;
		switch (filter.getOperator()) {
		case Filter.OP_AND:
			Junction andCri = Restrictions.conjunction();
			List<Filter> andList = (List<Filter>) filter.getValue();
			for(Filter f : andList){
				andCri.add(f.isSimpleFilter() ?
						buildCriterionBySimFilter(f) : buildCriterionByConnFilter(f));
			}
			criterion = andCri;
			break;
		case Filter.OP_OR:
			Junction orCri = Restrictions.disjunction();
			List<Filter> orList = (List<Filter>) filter.getValue();
			for(Filter f : orList){
				orCri.add(f.isSimpleFilter() ?
						buildCriterionBySimFilter(f) : buildCriterionByConnFilter(f));
			}
			criterion = orCri;
			break;
		}
		return criterion;
	}

}


4、使用测试,UserDao.java

package org.nercita.ntp.system.dao;

import java.util.Date;
import java.util.List;

import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.hibernate.transform.Transformers;
import org.nercita.ntp.system.domain.User;
import org.nercita.ntp.system.domain.reference.RoleType;
import org.nercita.ntp.system.domain.reference.UserState;
import org.nercita.ntp.system.domain.reference.UserType;
import org.nercita.ntp.system.domain.vo.UserVo;
import org.nercita.ntp.util.FilterDescriptor;
import org.nercita.ntp.util.KendoPage;
import org.nercita.ntp.util.SortDescriptor;
import org.nercita.core.orm.hibernate.HibernateBaseDao;
import org.springframework.stereotype.Repository;

/**
 * 用户持久类
 * @author zhangwenchao
 *
 */
@Repository("userDao")
public class UserDao extends HibernateBaseDao<User, String>{
	
	
	/**
	 * 根据用户名密码查询用户
	 * @param name
	 * @param password
	 * @return
	 */
	@SuppressWarnings("rawtypes")
	public User findByUsernameAndPassword(String name, String password) {
		String hql = "FROM User u where u.name=? and u.password=? and u.userState="+UserState.Enable.getValue();
		Query query = getSession().createQuery(hql)
		                 .setParameter(0, name)
		                 .setParameter(1, password);
		List list = query.list();		
		if(list !=null && list.size()>0){
			User u = (User)list.get(0);
			return u;
		}else{
			return null;
		}
	
	}
	
	
	/**
	 * 根据用户名密码查询用户
	 * @param name
	 * @param password
	 * @return
	 */
	@SuppressWarnings("rawtypes")
	public User findByUsernameAndPasswordAndImei(String name, String password,String imei) {
	
		String hql = "FROM User u where u.name=? and u.password=? and u.imei=? and u.userState="+UserState.Enable.getValue();
		Query query = getSession().createQuery(hql)
		                 .setParameter(0, name)
		                 .setParameter(1, password)
		                 .setParameter(2, imei);
		List list = query.list();		
		if(list !=null && list.size()>0){
			User u = (User)list.get(0);
			return u;
		}else{
			return null;
		}
	
	}
	
		
    
	/**
	 * 根据用户账户查询用户
	 * @param userName
	 * @return
	 */
	public User findByName(String userName) {
		
		return findUniqueByProperty("name", userName);
	}

	
	/**
	 * 查询一般用户列表
	 * @param page
	 * @return
	 */
	public KendoPage<User> findPageByQuery(KendoPage<User> page) {
				
		String hql = "FROM User u WHERE  u.userState=1";	
		if(page.getFilter()!=null && page.getFilter().size()!=0){	
			for(FilterDescriptor filter: page.getFilter()){
				
				if(!hql.toLowerCase().contains("where")){ 
					hql += " where ";
			    }else{  
			    	hql += " and ";   
			    }
				if(filter.getField().equals("name")){	
				    hql += "  u.name like '%"+filter.getValue()+"%'";
				}
				if(filter.getField().equals("userGroup")){
					hql += "  u.userGroup.name like '%"+filter.getValue()+"%'";
				}
			}
		}
			
		if(page.getSort()!=null && page.getSort().size()!=0){
			for(SortDescriptor sort: page.getSort()){
				if(!hql.toLowerCase().contains("order by")){
					hql += " order by ";
				}else{
					hql += ", ";
				} 		
				//如需对前台field中字段进行重命名则需在此进行判断调整
				if( sort.getField().equals("name")){
					hql += " u.name "+ sort.getDir()+ " ";
				}else if( sort.getField().equals("groupName")){
					hql += " u.groupName.name " +  sort.getDir()+ " ";
				}else{
					hql += " u."+sort.getField() + " " + sort.getDir();
				}				
		    }
			
		}else{
			hql += " order by u.name asc";
		}
		return (KendoPage<User>) findPageByHql(page, hql);
	}
	/**
	 * 查询所有系统用户列表
	 * @param page
	 * @return
	 */
	public KendoPage<User> findSystemUserPageByQuery(KendoPage<User> page, User user) {
		String hql = "FROM User u WHERE  u.name <> 'admin' ";
		if(user.getUserType() == UserType.System){
			hql += "and u.userType = "+UserType.System.getValue();
		}else{
			hql += "and u.id = '"+user.getId()+"' and u.userType = "+UserType.System.getValue();
		}
		if(page.getFilter()!=null && page.getFilter().size()!=0){	
			for(FilterDescriptor filter: page.getFilter()){
				if(!hql.toLowerCase().contains("where")){ 
					hql += " where ";
			    }else{  
			    	hql += " and ";   
			    }
				if(filter.getField().equals("name")){	
				    hql += "  u.name like '%"+filter.getValue()+"%'";
				}else if(filter.getField().equals("userGroup")){
					hql += "  u.userGroup.name like '%"+filter.getValue()+"%'";
				}else{
					hql += " u."+filter.getField()+" like '%"+filter.getValue()+"%'";
				}
				
				
			}
		}
			
		if(page.getSort()!=null && page.getSort().size()!=0){
			for(SortDescriptor sort: page.getSort()){
				if(!hql.toLowerCase().contains("order by")){
					hql += " order by ";
				}else{
					hql += ", ";
				} 		
				//如需对前台field中字段进行重命名则需在此进行判断调整
				if( sort.getField().equals("name")){
					hql += " u.name "+ sort.getDir()+ " ";
				}else if( sort.getField().equals("groupName")){
					hql += " u.groupName.name " +  sort.getDir()+ " ";
				}else{
					hql += " u."+sort.getField() + " " + sort.getDir();
				}				
		    }
			
		}else{
			hql += " order by u.name asc";
		}
		return (KendoPage<User>) findPageByHql(page, hql);
	}	
	
	

}

 

 

 

阅读更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zmx729618/article/details/54341662
文章标签: java 泛型 hibernate
个人分类: Java JPA/Hibernate
上一篇SpringMVC-redirect重定向传值
下一篇Spring实现分布式事务JTA(使用atomiko实现)
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭