package com.hasau.dao;
import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import org.hibernate.Criteria;
import org.hibernate.Hibernate;
import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.CriteriaSpecification;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.hibernate.metadata.ClassMetadata;
import com.hasau.support.Page;
import com.hasau.util.ReflectionUtils;
/**
* @desc
* @author hasau
* @E_Mail hasau@qq.com
* @Date Apr 11, 2013 10:59:53 AM
* @version 1.0.0
*/
public abstract class HibernateDao<T, PK extends Serializable>
{
protected Class<T> entityClass;
public abstract SessionFactory getSessionFactory();
/**
* 获取当前的session
* @return
*/
public Session getSession() {
return getSessionFactory().getCurrentSession();
}
public HibernateDao() {
this.entityClass = ReflectionUtils.getSuperClassGenricType(getClass());
}
public HibernateDao(final Class<T> entityClass) {
this.entityClass = entityClass;
}
@SuppressWarnings("unchecked")
public T findObject(final PK id) {
return (T) getSession().load(entityClass, id);
}
@SuppressWarnings("unchecked")
public T getObject(final PK id) {
return (T) getSession().get(entityClass, id);
}
/**
* 保存新增或修改的对象.<br>
* 主键==null 时才能 insert =="" 无效<br>
* 使用前先判断id是否为Blank,是设置id=null
*/
public void saveOrUpdateObject(final T entity) {
getSession().saveOrUpdate(entity);
}
public void saveObject(final T entity) {
getSession().save(entity);
}
public void updateObject(final T entity) {
getSession().update(entity);
}
public void mergeObject(final T entity) {
getSession().merge(entity);
}
/**
* 删除对象.
*
* @param entity 对象必须是session中的对象或含id属性的transient对象.
*/
public void destoryObject(final T entity) {
getSession().delete(entity);
}
/**
* 按id删除对象.<br>
* 先查出来,再删除,不推荐使用<br>
* 推荐执行hql删除
*/
public void destoryObject(final PK id) {
destoryObject(findObject(id));
}
/**
* 删除所有
* @param entities 必须有id存在
*/
public void destoryAllObject(final Collection<?> entities) {
if(entities == null) return;
for(Object entity : entities) {
getSession().delete(entity);
}
}
/**
* 获取全部对象.
*/
public List<T> findAllObjects() {
return findObjects();
}
/**
* 获取全部对象,支持排序.
* @param orderBy
* @param isAsc
* @return
*/
@SuppressWarnings("unchecked")
public List<T> findAllObjects(String orderBy, boolean isAsc) {
Criteria c = createCriteria();
if (isAsc) {
c.addOrder(Order.asc(orderBy));
} else {
c.addOrder(Order.desc(orderBy));
}
return c.list();
}
/**
* 按属性查找对象列表,匹配方式为相等.
* @param propertyName
* @param value
* @return
*/
public List<T> findObjectBy(final String propertyName, final Object value) {
Criterion criterion = Restrictions.eq(propertyName, value);
return findObjects(criterion);
}
/**
* 按属性查找唯一对象,匹配方式为相等.
* @param propertyName
* @param value
* @return
*/
@SuppressWarnings("unchecked")
public T findUniqueObjectBy(final String propertyName, final Object value) {
Criterion criterion = Restrictions.eq(propertyName, value);
return (T) createCriteria(criterion).uniqueResult();
}
/**
* 按id列表获取对象.
* @param ids
* @return
*/
public List<T> findObjectByIds(List<PK> ids) {
return findObjects(Restrictions.in(getIdName(), ids));
}
/**
* 按HQL查询对象列表.
* @param values 数量可变的参数,按顺序绑定.
* @param hql
* @param values
* @return
*/
@SuppressWarnings("unchecked")
public List<T> findObject(final String hql, final Object... values) {
return createQuery(hql, values).list();
}
/**
* 按HQL查询对象列表.
* @param values 命名参数,按名称绑定.
* @param hql
* @param values
* @return
*/
@SuppressWarnings("unchecked")
public List<T> findObject(final String hql, final Map<String, ?> values) {
return createQuery(hql, values).list();
}
/**
* 按HQL查询唯一对象.
* @param values 数量可变的参数,按顺序绑定.
* @param hql
* @param values
* @return
*/
@SuppressWarnings("unchecked")
public T findUniqueObject(final String hql, final Object... values) {
return (T) createQuery(hql, values).uniqueResult();
}
/**
* 按HQL查询唯一对象.
* @param values 命名参数,按名称绑定.
* @param hql
* @param values
* @return
*/
@SuppressWarnings("unchecked")
public T findUniqueObject(final String hql, final Map<String, ?> values) {
return (T) createQuery(hql, values).uniqueResult();
}
/**
* 执行HQL进行批量修改/删除操作.
* @param hql
* @param values
* @return
*/
public int executeUpdate(final String hql, final Object... values) {
return createQuery(hql, values).executeUpdate();
}
/**
* 执行HQL进行修改删除
* @return 更新记录数
* @param hql
* @param values
* @return
*/
public int executeUpdate(final String hql, final Map<String, ?> values) {
return createQuery(hql, values).executeUpdate();
}
/**
* 根据查询HQL与参数列表创建Query对象.
*
* 本类封装的find()函数全部默认返回对象类型为T,当不为T时使用本函数.
*
* @param values 数量可变的参数,按顺序绑定.
*/
public Query createQuery(final String queryString, final Object... values) {
Query query = getSession().createQuery(queryString);
loadQueryParameter(query, values);
return query;
}
/**
* 根据查询HQL与参数列表创建Query对象.
* @param values 命名参数,按名称绑定.
* @param queryString
* @param values
* @return
*/
public Query createQuery(final String queryString, final Map<String, ?> values) {
Query query = getSession().createQuery(queryString);
if (values != null) {
query.setProperties(values);
}
return query;
}
/**
* 按Criteria查询对象列表.
* @param criterions 数量可变的Criterion.
* @param criterions
* @return
*/
@SuppressWarnings("unchecked")
public List<T> findObjects(final Criterion... criterions) {
return createCriteria(criterions).list();
}
/**
* 按Criteria查询唯一对象.
* @param criterions 数量可变的Criterion.
* @param criterions
* @return
*/
@SuppressWarnings("unchecked")
public T findUniqueObject(final Criterion... criterions) {
return (T) createCriteria(criterions).uniqueResult();
}
/**
* 根据Criterion条件创建Criteria.
*
* 本类封装的find()函数全部默认返回对象类型为T,当不为T时使用本函数.
*
* @param criterions 数量可变的Criterion.
*/
public Criteria createCriteria(final Criterion... criterions) {
Criteria criteria = getSession().createCriteria(entityClass);
for (Criterion c : criterions) {
criteria.add(c);
}
return criteria;
}
/**
* 初始化对象.
* 使用load()方法得到的仅是对象Proxy, 在传到View层前需要进行初始化.
* 只初始化entity的直接属性,但不会初始化延迟加载的关联集合和属性.
* 如需初始化关联属性,可实现新的函数,执行:
* Hibernate.initialize(user.getRoles()),初始化User的直接属性和关联集合.
* Hibernate.initialize(user.getDescription()),初始化User的直接属性和延迟加载的Description属性.
*/
public void initEntity(T entity) {
Hibernate.initialize(entity);
}
/**
*
* @param entityList
*/
public void initEntity(List<T> entityList) {
for (T entity : entityList) {
Hibernate.initialize(entity);
}
}
/**
* 为Query添加distinct transformer.
* @param query
* @return
*/
public Query distinct(Query query) {
query.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);
return query;
}
/**
* 为Criteria添加distinct transformer.
* @param criteria
* @return
*/
public Criteria distinct(Criteria criteria) {
criteria.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);
return criteria;
}
/**
* 取得对象的主键名.
* @return
*/
public String getIdName() {
ClassMetadata meta = getSessionFactory().getClassMetadata(entityClass);
return meta.getIdentifierPropertyName();
}
public void clear() {
getSession().clear();
}
/**
* 此方法 有待完善
*/
public void evict(Object object) {
getSession().evict(object);
}
public void flush() {
getSession().flush();
}
/** 执行update delete 的HQL
* @param hql
*/
public void executeUpdateHql(final String hql,Object[] values){
Query query = getSession().createQuery(hql);
loadQueryParameter(query, values);
query.executeUpdate();
query= null;
}
/** 执行update delete 的SQL
* @param sql
*/
public void executeUpdateSql(final String sql,Object[] values){
SQLQuery query = getSession().createSQLQuery(sql);
loadQueryParameter(query, values);
query.executeUpdate();
query= null;
}
@SuppressWarnings("unchecked")
public List<T> findListHql(String hql,Object[] values){
Query query = createQueryHQL(hql);
loadQueryParameter(query, values);
List<T> list = query.list();
query = null;
hql = null;
return list;
}
/**
* 数组集合
* @param sql
* @param values
* @return
*/
@SuppressWarnings("unchecked")
public List findListSql(String sql,Object[] values){
SQLQuery query = createQuerySQL(sql);
loadQueryParameter(query, values);
List list = query.list();
query = null;
sql = null;
return list;
}
@SuppressWarnings("unchecked")
public List<T> findPage(Criteria criteria ,int pageSize,int currentpage){
criteria.setFirstResult((currentpage-1)*pageSize);
criteria.setMaxResults(pageSize);
return criteria.list();
}
@SuppressWarnings("unchecked")
public List<T> findPageHql(String hql,Object[] values,int pageSize,int currentpage){
Query query = createQueryHQL(hql);
loadQueryParameter(query, values);
query.setFirstResult((currentpage-1)*pageSize);
query.setMaxResults(pageSize);
List<T> list = query.list();
query = null;
hql = null;
return list;
}
@SuppressWarnings("unchecked")
public List<T> findPageSql(String sql,Object[] values,int pageSize,int currentpage){
SQLQuery query = createQuerySQL(sql);
loadQueryParameter(query, values);
query.setFirstResult((currentpage-1)*pageSize);
query.setMaxResults(pageSize);
List<T> list = query.list();
query = null;
sql = null;
return list;
}
/**
* 查询结果条数
* @param criteria
* @return
*/
public int countCriteriaResult(Criteria criteria){
return Integer.valueOf(criteria.setProjection(
Projections.rowCount()).uniqueResult().toString());
}
public int countQueryHQLResult(String hql,Object[] values){
hql = "SELECT COUNT(1) FROM ( "+hql+" )";
Query query = getSession().createQuery(hql);
loadQueryParameter(query, values);
int count = Integer.valueOf(query.uniqueResult().toString());
query=null;
hql = null;
return count;
}
public int countQuerySQLResult(String sql,Object[] values){
sql = "SELECT COUNT(1) FROM ( "+sql+" )";
SQLQuery query = getSession().createSQLQuery(sql);
loadQueryParameter(query, values);
int count = Integer.valueOf(query.uniqueResult().toString());
query=null;
sql = null;
return count;
}
public Criteria createCriteria(){
return getSession().createCriteria(entityClass);
}
public Query createQueryHQL(String hql){
return getSession().createQuery(hql);
}
public SQLQuery createQuerySQL(String sql){
return getSession().createSQLQuery(sql);
}
@SuppressWarnings("unchecked")
public void findPage(Criteria criteria ,Page<T> page){
//总记录 获取后取消 投影
Integer totalCount = Integer.valueOf(criteria.setProjection(Projections.rowCount()).uniqueResult().toString());
criteria.setProjection(null);
//查询分页信息
criteria.setFirstResult((page.getPageNo()-1)*page.getPageSize());
criteria.setMaxResults(page.getPageSize());
page.setTotalCount(totalCount);
page.setResult(criteria.list());
}
/** 装载 query 参数
* @param query
* @param values
*/
private void loadQueryParameter(Query query ,Object[] values ){
if(values!=null && values.length>0){
for(int i=0;i<values.length;i++){
query.setParameter(i, values[i]);
}
}
}
}