hibernategenericdao.java

来自「anewssystem新闻发布系统集成使用了spring hibernate f」· Java 代码 · 共 648 行 · 第 1/2 页

JAVA
648
字号
package anni.core.dao;

import java.io.Serializable;

import java.lang.reflect.InvocationTargetException;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import anni.core.page.Page;

import anni.core.utils.BeanUtils;

import org.apache.commons.beanutils.PropertyUtils;

import org.hibernate.Criteria;
import org.hibernate.Hibernate;
import org.hibernate.Query;

import org.hibernate.criterion.CriteriaSpecification;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projection;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;

import org.hibernate.impl.CriteriaImpl;

import org.hibernate.metadata.ClassMetadata;

import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import org.springframework.util.Assert;
import org.springframework.util.ReflectionUtils;


/**
 * Hibernate Dao的泛型基类.
 * <p/>
 * 继承于Spring的<code>HibernateDaoSupport</code>,提供分页函数和若干便捷查询方法,并对返回值作了泛型类型转换.
 *
 * @author calvin
 * @author tin
 * @see HibernateDaoSupport
 * @see HibernateEntityDao
 */
@SuppressWarnings("unchecked")
public class HibernateGenericDao extends HibernateDaoSupport {
    /**
     * 根据ID获取对象.
     * 实际调用Hibernate的session.get()方法返回实体或其proxy对象.
     * 如果对象不存在,返回null.
     *
     * @param entityClass 实体类型
     * @param id 主键
     * @param <T> 实体类型
     * @return 获取的对象
     */
    public <T> T get(Class<T> entityClass, Serializable id) {
        return (T) getHibernateTemplate().get(entityClass, id);
    }

    /**
     * 根据ID获取对象.
     * 实际调用Hibernate的session.load()方法返回实体或其proxy对象.
     * 网上有的地方说,对象不存在就抛出ObjectNotFindException,但实际使用的时候总是返回proxy。
     * 而在是具体使用的时候会出问题,根本没办法判断这个id是否存在,真是没办法。
     *
     * @param entityClass 实体类型
     * @param id 主键
     * @param <T> 实体类型
     * @return 获取的对象
     */
    public <T> T load(Class<T> entityClass, Serializable id) {
        return (T) getHibernateTemplate().load(entityClass, id);
    }

    /**
     * 获取全部对象.
     *
     * @param entityClass 实体类型
     * @param <T> 实体类型
     * @return 所有对象列表
     */
    public <T> List<T> getAll(Class<T> entityClass) {
        return getHibernateTemplate().loadAll(entityClass);
    }

    /**
     * 获取全部对象,带排序字段与升降序参数.
     *
     * @param entityClass 实体类型
     * @param orderBy 排序字段
     * @param isAsc 是否正序排列
     * @param <T> 实体类型
     * @return 所有对象列表
     */
    public <T> List<T> getAll(Class<T> entityClass, String orderBy,
        boolean isAsc) {
        Assert.hasText(orderBy);

        if (isAsc) {
            return getHibernateTemplate()
                       .findByCriteria(DetachedCriteria.forClass(
                    entityClass).addOrder(Order.asc(orderBy)));
        } else {
            return getHibernateTemplate()
                       .findByCriteria(DetachedCriteria.forClass(
                    entityClass).addOrder(Order.desc(orderBy)));
        }
    }

    /**
     * 保存对象.
     *
     * @param o 保存的对象
     */
    public void save(Object o) {
        getHibernateTemplate().saveOrUpdate(o);
    }

    /**
     * 删除对象.
     *
     * @param o 删除的对象
     */
    public void remove(Object o) {
        getHibernateTemplate().delete(o);
    }

    /**
     * 根据ID删除对象.
     *
     * @param entityClass 删除对象的类型
     * @param id 主键
     * @param <T> 删除对象的类型
     */
    public <T> void removeById(Class<T> entityClass, Serializable id) {
        remove(load(entityClass, id));
    }

    /**
     * 删除所有对象.
     *
     * @param all 删除对象的集合
     * @param <T> 删除对象的类型
     */
    public <T> void removeAll(Collection<T> all) {
        getHibernateTemplate().deleteAll(all);
    }

    /** * 刷新所有等待的保存,更新,删除操作,更新数据库. */
    public void flush() {
        getHibernateTemplate().flush();
    }

    /** * 删除Session缓存里的所有对象,取消所有等待的保存,更新,删除操作. */
    public void clear() {
        getHibernateTemplate().clear();
    }

    /**
     * 创建Query对象. 对于需要first,max,fetchsize,cache,cacheRegion等诸多设置的函数,可以在返回Query后自行设置.
     * 留意可以连续设置,如下:
     * <pre>
     * dao.getQuery(hql).setMaxResult(100).setCacheable(true).list();
     * </pre>
     * 调用方式如下:
     * <pre>
     *        dao.createQuery(hql)
     *        dao.createQuery(hql,arg0);
     *        dao.createQuery(hql,arg0,arg1);
     *        dao.createQuery(hql,new Object[arg0,arg1,arg2])
     * </pre>
     *
     * @param hql 查询语句
     * @param values 可变参数
     * @return 返回Query
     */
    public Query createQuery(String hql, Object... values) {
        Assert.hasText(hql);

        Query query = getSession().createQuery(hql);

        for (int i = 0; i < values.length; i++) {
            query.setParameter(i, values[i]);
        }

        return query;
    }

    /**
     * 创建Criteria对象.
     *
     * @param entityClass 实体类型
     * @param criterions 可变的Restrictions条件列表,见{@link #createQuery(String,Object...)}
     * @param <T> 实体类型
     * @return 构造的Criteria
     */
    public <T> Criteria createCriteria(Class<T> entityClass,
        Criterion... criterions) {
        Criteria criteria = getSession().createCriteria(entityClass);

        for (Criterion c : criterions) {
            criteria.add(c);
        }

        return criteria;
    }

    /**
     * 创建Criteria对象,带排序字段与升降序字段.
     *
     * @see #createCriteria(Class,Criterion[])
     *
     * @param entityClass 实体类型
     * @param orderBy 排序字段
     * @param isAsc 是否正序排列
     * @param criterions 可变的Restrictions条件列表,见{@link #createQuery(String,Object...)}
     * @param <T> 实体类型
     * @return 构造的Criteria
     */
    public <T> Criteria createCriteria(Class<T> entityClass,
        String orderBy, boolean isAsc, Criterion... criterions) {
        Assert.hasText(orderBy);

        Criteria criteria = createCriteria(entityClass, criterions);

        if (isAsc) {
            criteria.addOrder(Order.asc(orderBy));
        } else {
            criteria.addOrder(Order.desc(orderBy));
        }

        return criteria;
    }

    /**
     * 根据hql查询,直接使用HibernateTemplate的find函数.
     *
     * @param hql 查询语句
     * @param values 可变参数,见{@link #createQuery(String,Object...)}
     * @return 查询结果
     */
    public List find(String hql, Object... values) {
        Assert.hasText(hql);

        return getHibernateTemplate().find(hql, values);
    }

    /**
     * 根据属性名和属性值查询对象.
     *
     * @param entityClass 实体类型
     * @param propertyName 属性名
     * @param value 属性值
     * @param <T> 实体类型
     * @return 符合条件的对象列表
     */
    public <T> List<T> findBy(Class<T> entityClass, String propertyName,
        Object value) {
        Assert.hasText(propertyName);

        return createCriteria(entityClass,
            Restrictions.eq(propertyName, value)).list();
    }

    /**
     * 根据属性名和属性值查询对象,带排序参数.
     *
     * @param entityClass 实体类型
     * @param propertyName 属性名
     * @param value 属性值
     * @param orderBy 排序字段
     * @param isAsc 是否正序
     * @param <T> 实体类型
     * @return 符合条件的对象列表
     */
    public <T> List<T> findBy(Class<T> entityClass, String propertyName,
        Object value, String orderBy, boolean isAsc) {
        Assert.hasText(propertyName);
        Assert.hasText(orderBy);

        return createCriteria(entityClass, orderBy, isAsc,
            Restrictions.eq(propertyName, value)).list();
    }

    /**
     * 根据属性名和属性值查询唯一对象.
     *
     * @param entityClass 实体类型
     * @param propertyName 属性名
     * @param value 属性值
     * @param <T> 实体类型
     * @return 符合条件的唯一对象 or null if not found.
     */
    public <T> T findUniqueBy(Class<T> entityClass, String propertyName,
        Object value) {
        Assert.hasText(propertyName);

        return (T) createCriteria(entityClass,
            Restrictions.eq(propertyName, value)).uniqueResult();
    }

    /**
     * 分页查询函数,使用hql.
     *
     * FIXME: 如果出现group by,having子句,分页就会出现问题
     * @param hql 查询语句
     * @param pageNo 页号,从1开始
     * @param pageSize 每页包含多少条记录
     * @param values 不定参数,hql需要的参数
     * @return 分页结果
     */
    public Page pagedQuery(String hql, int pageNo, int pageSize,
        Object... values) {
        Assert.hasText(hql);
        Assert.isTrue(pageNo >= 1, "pageNo should start from 1");

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?