HibernateDao层逻辑

来源:互联网 发布:amx m4 mle.54数据 编辑:程序博客网 时间:2024/06/03 19:01
package com.idoo.iosms.core.hibernate.hibernate;

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

import org.apache.commons.lang.StringUtils;
import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.CriteriaSpecification;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Disjunction;
import org.hibernate.criterion.MatchMode;
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.transform.ResultTransformer;
import org.springframework.util.Assert;

import com.idoo.iosms.core.hibernate.PageGenericDao;
import com.idoo.iosms.core.utils.Page;
import com.idoo.iosms.core.utils.PropertyFilter;
import com.idoo.iosms.core.utils.ReflectionUtils;
import com.idoo.iosms.core.utils.PropertyFilter.MatchType;

public class HibernateDao<T, PK extends Serializable> extends
        HibernateGenericDao<T, PK> implements PageGenericDao<T, PK> {

    public HibernateDao() {
        super();
    }

    public HibernateDao(final SessionFactory sessionFactory,
            final Class<T> entityClass) {
        super(sessionFactory, entityClass);
    }

    @SuppressWarnings("unchecked")
    public Page<T> queryPage(Page<T> page, String hql, Object... values) {
        // TODO Auto-generated method stub

        Assert.notNull(page, "page不能为空");

        Query q = createQuery(hql, values);

        if (page.isAutoCount()) {
            int totalCount = countHqlResult(hql, values);
            page.setTotalCount(totalCount);
        }

        setPageParameter(q, page);
        List<T> result = q.list();
        page.setResultList(result);
        return page;
    }

    @SuppressWarnings("unchecked")
    public Page<T> queryPage(Page<T> page, String hql,
            Map<String, Object> values) {
        // TODO Auto-generated method stub
        Assert.notNull(page, "page不能为空");

        Query q = createQuery(hql, values);

        if (page.isAutoCount()) {
            int totalCount = countHqlResult(hql, values);
            page.setTotalCount(totalCount);
        }

        setPageParameter(q, page);
        List<T> result = q.list();
        page.setResultList(result);

        return page;
    }

    @SuppressWarnings("unchecked")
    public Page<T> queryPage(Page<T> page, Criterion... criterions) {
        // TODO Auto-generated method stub
        Assert.notNull(page, "page不能为空");

        Criteria c = createCriteria(criterions);

        if (page.isAutoCount()) {
            int totalCount = countCriteriaResult(c);
            page.setTotalCount(totalCount);
        }

        setPageParameter(c, page);
        List<T> result = c.list();
        page.setResultList(result);
        return page;
    }

    public Page<T> queryPage(final Page<T> page,
            final List<PropertyFilter> filters) {
        Criterion[] criterions = buildPropertyFilterCriterions(filters);
        return queryPage(page, criterions);
    }

    @SuppressWarnings("unchecked")
    public int countCriteriaResult(Criteria c) {
        // TODO Auto-generated method stub
        CriteriaImpl impl = (CriteriaImpl) c;

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

        List<CriteriaImpl.OrderEntry> orderEntries = null;
        try {
            orderEntries = (List<CriteriaImpl.OrderEntry>) ReflectionUtils
                    .getFieldValue(impl, "orderEntries");
            ReflectionUtils.setFieldValue(impl, "orderEntries",
                    new ArrayList<Object>());
        } catch (Exception e) {
            logger.error("不可能抛出的异常:{}", e.getMessage());
        }

        // 执行Count查询
        int totalCount = (Integer) c.setProjection(Projections.rowCount())
                .uniqueResult();

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

        if (projection == null) {
            c.setResultTransformer(CriteriaSpecification.ROOT_ENTITY);
        }
        if (transformer != null) {
            c.setResultTransformer(transformer);
        }
        try {
            ReflectionUtils.setFieldValue(impl, "orderEntries", orderEntries);
        } catch (Exception e) {
            logger.error("不可能抛出的异常:{}", e.getMessage());
        }

        return totalCount;
    }

    public int countHqlResult(String hql, Object... values) {
        String fromHql = hql;

        // select子句与order by子句会影响count查询,进行简单的排除.
        fromHql = "from " + StringUtils.substringAfter(fromHql, "from");
        fromHql = StringUtils.substringBefore(fromHql, "order by");

        String selectHql = "*";
        // 如果含有 distinct 描述符,进行简单处理
        if (StringUtils.indexOf(hql, "distinct") != -1) {
            selectHql = StringUtils.substringBetween(hql, "select", "from")
                    .trim();
        }
        String countHql = "select count(" + selectHql + ") " + fromHql;

        try {
            Long count = findUnique(countHql, values);
            return count.intValue();
        } catch (Exception e) {
            throw new RuntimeException("hql can't be auto count, hql is:"
                    + countHql, e);
        }
    }

    public int countHqlResult(String hql, Map<String, Object> values) {
        // TODO Auto-generated method stub
        String fromHql = hql;
        // select子句与order by子句会影响count查询,进行简单的排除.
        fromHql = "from " + StringUtils.substringAfter(fromHql, "from");
        fromHql = StringUtils.substringBefore(fromHql, "order by");

        String countHql = "select count(*) " + fromHql;

        try {
            Long count = findUnique(countHql, values);
            return count.intValue();
        } catch (Exception e) {
            throw new RuntimeException("hql can't be auto count, hql is:"
                    + countHql, e);
        }
    }

    /**
     *
     * Description : 设置分页参数到Query对象,辅助函数
     *
     * @param q
     * @param page
     * @return
     *
     */
    @SuppressWarnings("static-access")
    protected Query setPageParameter(final Query q, final Page<T> page) {
        // 如果每页显示的记录数 为-1,查询所有记录 ,不做分页
        if (page.getPageSize() != page.ALL_SIZE) {
            q.setFirstResult(page.getBeginCount());
            q.setMaxResults(page.getPageSize());
        }
        return q;
    }

    /**
     *
     * Description : 设置分页参数到Criteria对象,辅助函数
     *
     * @param c
     * @param page
     * @return
     *
     */
    protected Criteria setPageParameter(final Criteria c, final Page<T> page) {
        c.setFirstResult(page.getCurrentPage() - 1);
        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]));
                }
            }
        }
        return c;
    }

    /**
     *
     * Description : 按属性条件列表创建Criterion数组,辅助函数
     *
     * @param filters
     * @return
     *
     */
    protected Criterion[] buildPropertyFilterCriterions(
            final List<PropertyFilter> filters) {
        List<Criterion> criterionList = new ArrayList<Criterion>();
        for (PropertyFilter filter : filters) {
            if (!filter.isMultiProperty()) { // 只有一个属性需要比较的情况.
                Criterion criterion = buildPropertyFilterCriterion(
                        filter.getPropertyName(), filter.getPropertyValue(),
                        filter.getMatchType());
                criterionList.add(criterion);
            } else {// 包含多个属性需要比较的情况,进行or处理.
                Disjunction disjunction = Restrictions.disjunction();
                for (String param : filter.getPropertyNames()) {
                    Criterion criterion = buildPropertyFilterCriterion(param,
                            filter.getPropertyValue(), filter.getMatchType());
                    disjunction.add(criterion);
                }
                criterionList.add(disjunction);
            }
        }
        return criterionList.toArray(new Criterion[criterionList.size()]);
    }

    /**
     *
     * Description : 按属性条件参数创建Criterion,辅助函数
     *
     * @param propertyName
     * @param propertyValue
     * @param matchType
     * @return
     *
     */
    protected Criterion buildPropertyFilterCriterion(final String propertyName,
            final Object propertyValue, final MatchType matchType) {
        Assert.hasText(propertyName, "propertyName不能为空");
        Criterion criterion = null;
        try {

            // 根据MatchType构造criterion
            if (MatchType.EQ.equals(matchType)) {
                criterion = Restrictions.eq(propertyName, propertyValue);
            } else if (MatchType.LIKE.equals(matchType)) {
                criterion = Restrictions.like(propertyName,
                        (String) propertyValue, MatchMode.ANYWHERE);
            } else if (MatchType.LE.equals(matchType)) {
                criterion = Restrictions.le(propertyName, propertyValue);
            } else if (MatchType.LT.equals(matchType)) {
                criterion = Restrictions.lt(propertyName, propertyValue);
            } else if (MatchType.GE.equals(matchType)) {
                criterion = Restrictions.ge(propertyName, propertyValue);
            } else if (MatchType.GT.equals(matchType)) {
                criterion = Restrictions.gt(propertyName, propertyValue);
            }
        } catch (Exception e) {
            throw ReflectionUtils.convertReflectionExceptionToUnchecked(e);
        }
        return criterion;
    }

}


package com.idoo.iosms.core.hibernate.hibernate;

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

import org.apache.commons.lang.StringUtils;
import org.hibernate.Criteria;
import org.hibernate.Hibernate;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Criterion;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.util.Assert;

import com.idoo.iosms.core.hibernate.GenericDao;
import com.idoo.iosms.core.utils.ReflectionUtils;

public class HibernateGenericDao<T, PK extends Serializable> implements
        GenericDao<T, PK> {

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

    protected SessionFactory sessionFactory;

    protected Class<T> entityClass;

    public HibernateGenericDao() {
        this.entityClass = ReflectionUtils.getSuperClassGenricType(getClass());
    }

    public HibernateGenericDao(final SessionFactory sessionFactory,
            final Class<T> entityClass) {
        this.sessionFactory = sessionFactory;
        this.entityClass = entityClass;
    }

    public SessionFactory getSessionFactory() {
        return sessionFactory;
    }

    @Autowired
    public void setSessionFactory(
            final @Qualifier("sessionFactory") SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }

    public Session getSession() {

        return sessionFactory.getCurrentSession();
    }

    public void delete(T entity) {

        Assert.notNull(entity, "entity不能为空");
        getSession().delete(entity);
        logger.debug("delete entity: {}", entity);
    }

    @SuppressWarnings("unchecked")
    public <X> List<X> query(String hql, Object... values) {

        return createQuery(hql, values).list();
    }

    @SuppressWarnings("unchecked")
    public <X> List<X> query(String hql, Map<String, Object> values) {

        return createQuery(hql, values).list();
    }

    @SuppressWarnings("unchecked")
    public <X> X findUnique(String hql, Object... values) {

        return (X) createQuery(hql, values).uniqueResult();
    }

    @SuppressWarnings("unchecked")
    public <X> X findUnique(String hql, Map<String, Object> values) {

        return (X) createQuery(hql, values).uniqueResult();
    }

    @SuppressWarnings("unchecked")
    public T findUnique(final Criterion... criterions) {
        return (T) createCriteria(criterions).uniqueResult();
    }

    @SuppressWarnings("unchecked")
    public T get(Serializable id) {
        Assert.notNull(id, "id不能为空");
        return (T) getSession().get(entityClass, id);
    }

    public Serializable save(T entity) {

        Assert.notNull(entity, "entity不能为空");
        Serializable id = getSession().save(entity);
        logger.debug("save entity: {}", entity);
        return id;
    }

    public void saveOrUpdate(T entity) {

        Assert.notNull(entity, "entity不能为空");
        getSession().saveOrUpdate(entity);
        logger.debug("save entity: {}", entity);
    }

    public void update(T entity) {

        Assert.notNull(entity, "entity不能为空");
        getSession().update(entity);
        logger.debug("save entity: {}", entity);

    }

    public Query createQuery(String queryString, Map<String, Object> values) {

        Assert.hasText(queryString, "queryString不能为空");
        Query query = getSession().createQuery(queryString);
        query.setCacheable(true);
        ;
        if (values != null) {
            query.setProperties(values);
        }

        return query;
    }

    public Query createQuery(String queryString, Object... values) {

        Assert.hasText(queryString, "queryString不能为空");
        Query query = getSession().createQuery(queryString);
        query.setCacheable(true);
        ;
        if (values != null) {
            for (int i = 0; i < values.length; i++) {
                if (values[i] != null
                        && StringUtils.isNotEmpty(values[i].toString()))
                    query.setParameter(i, values[i]);
            }
        }

        return query;
    }

    public int executeUpdate(final String hql, final Object... values) {

        return createQuery(hql, values).executeUpdate();
    }

    public int executeUpdate(final String hql, final Map<String, Object> values) {
        return createQuery(hql, values).executeUpdate();
    }

    public void initEntity(T entity) {
        Hibernate.initialize(entity);
    }

    public void initEntity(List<T> entityList) {
        for (T entity : entityList) {
            Hibernate.initialize(entity);
        }
    }

    /**
     *
     * Description : 根据Criterion条件创建Criteria
     *
     * @param criterions
     * @return
     *
     */
    public Criteria createCriteria(final Criterion... criterions) {
        Criteria criteria = getSession().createCriteria(entityClass);
        for (Criterion c : criterions) {
            criteria.add(c);
        }
        return criteria;
    }

}

package com.idoo.iosms.core.hibernate;

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

import org.hibernate.Query;
import org.hibernate.criterion.Criterion;

/**
 *
 * @param <T>
 * @param <ID>
 * @Description : 基类 DAO 接口
 */
public interface GenericDao<T, PK extends Serializable> {

    /**
     *
     * Description : 保存 实体对象
     *
     * @param entity
     *
     */
    public Serializable save(final T entity);

    /**
     *
     * Description : 删除 实体对象
     *
     * @param entity
     *
     */
    public void delete(final T entity);

    /**
     *
     * Description : 获取 实体对象
     *
     * @param id
     * @return
     *
     */
    public T get(final PK id);

    /**
     *
     * Description : 更新 实体对象
     *
     * @param entity
     *
     */
    public void update(final T entity);

    /**
     *
     * Description : 保存或更新 实体对象
     *
     * @param entity
     *
     */
    public void saveOrUpdate(final T entity);

    /**
     *
     * Description : 初始化对象. 使用load()方法得到的仅是对象Proxy, 在传到View层前需要进行初始化.
     * 只初始化entity的直接属性,但不会初始化延迟加载的关联集合和属性. 如需初始化关联属性,可实现新的函数,执行:
     * Hibernate.initialize(user.getRoles()),初始化User的直接属性和关联集合.
     * Hibernate.initialize
     * (user.getDescription()),初始化User的直接属性和延迟加载的Description属性.
     *
     *
     * @param entity
     *
     */
    public void initEntity(T entity);

    /**
     *
     * Description : 初始化对象
     *
     * @param entityList
     *
     */
    public void initEntity(List<T> entityList);

    /**
     *
     * Description : 按HQL查询对象列表
     *
     * @param <X>
     * @param hql
     * @param values
     * @return
     *
     */
    public <X> List<X> query(final String hql, final Object... values);

    /**
     *
     * Description : 按HQL查询对象列表
     *
     * @param <X>
     * @param hql
     * @param values
     * @return
     *
     */
    public <X> List<X> query(final String hql, final Map<String, Object> values);

    /**
     *
     * Description : 按HQL查询唯一对象
     *
     * @param <X>
     * @param hql
     * @param values
     * @return
     *
     */
    public <X> X findUnique(final String hql, final Object... values);

    /**
     *
     * Description : 按HQL查询唯一对象
     *
     * @param <X>
     * @param hql
     * @param values
     * @return
     *
     */
    public <X> X findUnique(final String hql, final Map<String, Object> values);

    /**
     *
     * Description : 按Criteria查询唯一对象
     *
     * @param criterions
     * @return
     *
     */
    public T findUnique(final Criterion... criterions);

    /**
     *
     * Description : 根据查询HQL与参数列表创建Query对象
     *
     * @param queryString
     * @param values
     * @return
     *
     */
    public Query createQuery(final String queryString, final Object... values);

    /**
     *
     * Description : 根据查询HQL与参数列表创建Query对象
     *
     * @param queryString
     * @param values
     * @return
     *
     */
    public Query createQuery(final String queryString,
            final Map<String, Object> values);

    /**
     *
     * Description : 根据查询HQL与参数列表 执行
     *
     * @param queryString
     * @param values
     * @return
     *
     */
    public int executeUpdate(final String queryString, final Object... values);

    /**
     *
     * Description : 根据查询HQL与参数列表 执行
     *
     * @param queryString
     * @param values
     * @return
     *
     */
    public int executeUpdate(final String queryString,
            final Map<String, Object> values);
}

package com.idoo.iosms.core.utils;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;

import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.beanutils.converters.DateConverter;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.Assert;

/**
 *
 * 反射的Util函数集合 提供访问私有变量,获取泛型类型Class,提取集合中元素的属性,转换字符串到对象等Util函数
 */
public class ReflectionUtils {

    private static Logger logger = LoggerFactory
            .getLogger(ReflectionUtils.class);

    /**
     *
     * Description : 直接读取对象属性值, 无视private/protected修饰符, 不经过getter函数.
     *
     * @param object
     * @param fieldName
     * @return
     *
     */
    public static Object getFieldValue(final Object object,
            final String fieldName) {
        Field field = getDeclaredField(object, fieldName);

        if (field == null)
            throw new IllegalArgumentException("Could not find field ["
                    + fieldName + "] on target [" + object + "]");

        makeAccessible(field);

        Object result = null;
        try {
            result = field.get(object);
        } catch (IllegalAccessException e) {
            logger.error("不可能抛出的异常{}", e.getMessage());
        }
        return result;
    }

    /**
     *
     * Description : 直接设置对象属性值, 无视private/protected修饰符, 不经过setter函数.
     *
     * @param object
     * @param fieldName
     * @param value
     *
     */
    public static void setFieldValue(final Object object,
            final String fieldName, final Object value) {
        Field field = getDeclaredField(object, fieldName);

        if (field == null)
            throw new IllegalArgumentException("Could not find field ["
                    + fieldName + "] on target [" + object + "]");

        makeAccessible(field);

        try {
            field.set(object, value);
        } catch (IllegalAccessException e) {
            logger.error("不可能抛出的异常:{}", e.getMessage());
        }
    }

    /**
     *
     * Description : 直接调用对象方法, 无视private/protected修饰符.
     *
     * @param object
     * @param methodName
     * @param parameterTypes
     * @param parameters
     * @return
     *
     */
    public static Object invokeMethod(final Object object,
            final String methodName, final Class<?>[] parameterTypes,
            final Object[] parameters) {
        Method method = getDeclaredMethod(object, methodName, parameterTypes);
        if (method == null)
            throw new IllegalArgumentException("Could not find method ["
                    + methodName + "] on target [" + object + "]");

        method.setAccessible(true);

        try {
            return method.invoke(object, parameters);
        } catch (Exception e) {
            throw convertReflectionExceptionToUnchecked(e);
        }
    }

    /**
     *
     * Description : 循环向上转型, 获取对象的DeclaredField. 如向上转型到Object仍无法找到, 返回null.
     *
     * @param object
     * @param fieldName
     * @return
     *
     */
    protected static Field getDeclaredField(final Object object,
            final String fieldName) {
        Assert.notNull(object, "object不能为空");
        Assert.hasText(fieldName, "fieldName");
        for (Class<?> superClass = object.getClass(); superClass != Object.class; superClass = superClass
                .getSuperclass()) {
            try {
                return superClass.getDeclaredField(fieldName);
            } catch (NoSuchFieldException e) {
                // Field不在当前类定义,继续向上转型
            }
        }
        return null;
    }

    /**
     *
     * Description : 强行设置Field可访问.
     *
     * @param field
     *
     */
    protected static void makeAccessible(final Field field) {
        if (!Modifier.isPublic(field.getModifiers())
                || !Modifier.isPublic(field.getDeclaringClass().getModifiers())) {
            field.setAccessible(true);
        }
    }

    /**
     *
     * Description : 循环向上转型,获取对象的DeclaredMethod. 如向上转型到Object仍无法找到, 返回null.
     *
     * @param object
     * @param methodName
     * @param parameterTypes
     * @return
     *
     */
    protected static Method getDeclaredMethod(Object object, String methodName,
            Class<?>[] parameterTypes) {
        Assert.notNull(object, "object不能为空");

        for (Class<?> superClass = object.getClass(); superClass != Object.class; superClass = superClass
                .getSuperclass()) {
            try {
                return superClass.getDeclaredMethod(methodName, parameterTypes);
            } catch (NoSuchMethodException e) {
                // Method不在当前类定义,继续向上转型
            }
        }
        return null;
    }

    /**
     *
     * Description : 通过反射,获得Class定义中声明的父类的泛型参数的类型. 如无法找到, 返回Object.class.
     *
     * @param <T>
     * @param clazz
     * @return
     *
     */
    @SuppressWarnings("unchecked")
    public static <T> Class<T> getSuperClassGenricType(final Class clazz) {
        return getSuperClassGenricType(clazz, 0);
    }

    /**
     * 通过反射,获得定义Class时声明的父类的泛型参数的类型. 如无法找到, 返回Object.class.
     *
     * 如public UserDao extends HibernateDao<User,Long>
     *
     * @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 getSuperClassGenricType(final Class clazz,
            final int index) {

        Type genType = clazz.getGenericSuperclass();

        if (!(genType instanceof ParameterizedType)) {
            logger.warn(clazz.getSimpleName()
                    + "'s superclass not ParameterizedType");
            return Object.class;
        }

        Type[] params = ((ParameterizedType) genType).getActualTypeArguments();

        if (index >= params.length || index < 0) {
            logger.warn("Index: " + index + ", Size of "
                    + clazz.getSimpleName() + "'s Parameterized Type: "
                    + params.length);
            return Object.class;
        }
        if (!(params[index] instanceof Class)) {
            logger.warn(clazz.getSimpleName()
                    + " not set the actual class on superclass generic parameter");
            return Object.class;
        }

        return (Class) params[index];
    }

    /**
     * 提取集合中的对象的属性(通过getter函数), 组合成List.
     *
     * @param collection
     *            来源集合.
     * @param propertyName
     *            要提取的属性名.
     */
    @SuppressWarnings("unchecked")
    public static List convertElementPropertyToList(
            final Collection collection, final String propertyName) {
        List list = new ArrayList();

        try {
            for (Object obj : collection) {
                list.add(PropertyUtils.getProperty(obj, propertyName));
            }
        } catch (Exception e) {
            throw convertReflectionExceptionToUnchecked(e);
        }

        return list;
    }

    /**
     * 提取集合中的对象的属性(通过getter函数), 组合成由分割符分隔的字符串.
     *
     * @param collection
     *            来源集合.
     * @param propertyName
     *            要提取的属性名.
     * @param separator
     *            分隔符.
     */
    @SuppressWarnings("unchecked")
    public static String convertElementPropertyToString(
            final Collection collection, final String propertyName,
            final String separator) {
        List list = convertElementPropertyToList(collection, propertyName);
        return StringUtils.join(list, separator);
    }

    /**
     * 转换字符串类型到clazz的property类型的值.
     *
     * @param value
     *            待转换的字符串
     * @param clazz
     *            提供类型信息的Class
     * @param propertyName
     *            提供类型信息的Class的属性.
     */
    public static Object convertValue(Object value, Class<?> toType) {
        try {
            DateConverter dc = new DateConverter();
            dc.setUseLocaleFormat(true);
            dc.setPatterns(new String[] { "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss" });
            ConvertUtils.register(dc, Date.class);
            return ConvertUtils.convert(value, toType);
        } catch (Exception e) {
            throw convertReflectionExceptionToUnchecked(e);
        }
    }

    /**
     *
     * Description : 将反射时的checked exception转换为unchecked exception.
     *
     * @param e
     * @return
     *
     */
    public static RuntimeException convertReflectionExceptionToUnchecked(
            Exception e) {
        if (e instanceof IllegalAccessException
                || e instanceof IllegalArgumentException
                || e instanceof NoSuchMethodException)
            return new IllegalArgumentException("Reflection Exception.", e);
        else if (e instanceof InvocationTargetException)
            return new RuntimeException("Reflection Exception.",
                    ((InvocationTargetException) e).getTargetException());
        else if (e instanceof RuntimeException) {
            return (RuntimeException) e;
        }
        return new RuntimeException("Unexpected Checked Exception.", e);
    }

}

package com.idoo.iosms.core.hibernate;

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

import org.hibernate.Criteria;
import org.hibernate.criterion.Criterion;

import com.idoo.iosms.core.utils.Page;
import com.idoo.iosms.core.utils.PropertyFilter;


public interface PageGenericDao<T, PK extends Serializable> extends GenericDao<T, PK> {
    
    /**
     *
     * Description     : 按HQL分页查询
     *
     * @param page
     * @param hql
     * @param values
     * @return
     *
     */
    public Page<T> queryPage(final Page<T> page, final String hql, final Object... values);
    
    /**
     *
     * Description     : 按HQL分页查询
     *
     * @param page
     * @param hql
     * @param values
     * @return
     *
     */
    public Page<T> queryPage(final Page<T> page, final String hql, final Map<String, Object> values);

    /**
     *
     * Description     : 按Criteria分页查询
     *
     * @param page
     * @param criterions
     * @return
     *
     */
    public Page<T> queryPage(final Page<T> page, final Criterion... criterions);
    
    /**
     *
     * Description     : 按属性过滤条件列表分页查找对象
     *
     * @param page
     * @param filters
     * @return
     *
     */
    public Page<T> queryPage(final Page<T> page, final List<PropertyFilter> filters);
    
    /**
     *
     * Description     : 执行count查询获得本次Hql查询所能获得的对象总数
     *
     * @param hql
     * @param values
     * @return
     *
     */
    public int countHqlResult(final String hql, final Object... values);
    
    /**
     *
     * Description     : 执行count查询获得本次Hql查询所能获得的对象总数
     *
     * @param hql
     * @param values
     * @return
     *
     */
    public int countHqlResult(final String hql, final Map<String, Object> values);
    
    /**
     *
     * Description     : 执行count查询获得本次Criteria查询所能获得的对象总数
     *
     * @param c
     * @return
     *
     */
    public int countCriteriaResult(final Criteria c);
}

package com.idoo.iosms.core.utils;

import java.util.Collections;
import java.util.List;

import org.apache.commons.lang.StringUtils;

public class Page<T>
{

    public static final int ALL_SIZE = -1;// 查询所有记录

    public static final int FRONT_SIZE = 4; // 前台展示的页面大小

    public static final int FIRST_PAGE = 1; // 第一页

    public static final int DEFAULT_SIZE = 10; // 每页默认显示10条

    public static final String ASC = "asc";

    public static final String DESC = "desc";

    private int beginCount; // 开始的记录数

    private int totalCount; // 记录总数

    private int pageSize; // 每页显示的记录数

    private int totalPage; // 总页数

    private int currentPage; // 当前页码

    private int prePage;

    private int nextPage;

    @SuppressWarnings("unused")
    private boolean hasPrePage; // 是否有上一页

    @SuppressWarnings("unused")
    private boolean hasNextPage; // 是否有下一页

    private boolean autoCount = true;// 是否计算记录总数

    private String orderBy; // 排序字段

    private String order; // 排序方式

    private String resultContent; // 基于文本的分页

    private List<T> resultList = Collections.emptyList(); // 基于记录的分页

    public Page()
    {

    }

    public static Page<String> getBlankPage(int pageSize)
    {
        Page<String> page = new Page<String>(0, pageSize);
        page.setResultContent("");
        return page;
    }

    public Page(List<T> resultList)
    {
        this.resultList = resultList;
    }

    public Page(int totalCount, int pageSize)
    {
        this(totalCount, pageSize, 1);
    }

    public Page(int totalCount, int pageSize, int currentPage)
    {
        if (pageSize > 0)
        {
            this.pageSize = pageSize;
        } else
        {
            this.pageSize = DEFAULT_SIZE;
        }

        this.totalCount = totalCount;

        if (totalCount <= 0)
        {
            this.totalPage = 1;
        } else
        {
            this.totalPage = (totalCount - 1) / pageSize + 1;
        }

        setCurrentPage(currentPage);
    }

    public Page(List<T> resultList, int totalCount, int pageSize,
            int currentPage)
    {
        this(totalCount, pageSize, currentPage);
        this.resultList = resultList;
    }

    public Page(String resultContent, int totalCount, int pageSize,
            int currentPage)
    {
        this(totalCount, pageSize, currentPage);
        this.resultContent = resultContent;
    }

    public void setCurrentPage(int currentPage)
    {
        if (currentPage <= 0)
        {
            currentPage = FIRST_PAGE;
        }
        this.currentPage = currentPage;
        this.beginCount = (currentPage - 1) * pageSize;

        if (currentPage > 1)
        {
            this.setHasPrePage(true);
            this.prePage = currentPage - 1;
        } else
        {
            this.setHasPrePage(false);
        }

        if (currentPage < totalPage)
        {
            this.setHasNextPage(true);
            this.nextPage = currentPage + 1;
        } else
        {
            this.setHasNextPage(false);
        }

    }

    public int getBeginCount()
    {
        return beginCount;
    }

    public int getTotalCount()
    {
        return totalCount;
    }

    @SuppressWarnings("static-access")
    public int getPageSize()
    {
        if (pageSize <= 0 && pageSize != -1)
        {
            pageSize = this.DEFAULT_SIZE;
        }
        return pageSize;
    }

    /**
     *
     * Description : 根据pageSize与totalCount计算总页数
     *
     * @return
     *
     */
    public int getTotalPage()
    {
        if (totalCount < 0)
            totalPage = -1;
        if (pageSize == -1)
        {
            totalPage = 1;
        }
        totalPage = totalCount / pageSize;
        if (totalCount % pageSize > 0)
        {
            totalPage++;
        }

        return totalPage;
    }

    @SuppressWarnings("static-access")
    public int getCurrentPage()
    {
        if (currentPage <= 0)
        {
            currentPage = this.FIRST_PAGE;
        }
        return currentPage;
    }

    /**
     *
     * Description : 是否还有上一页
     *
     * @return
     *
     */
    public boolean isHasPrePage()
    {
        return hasPrePage = (currentPage - 1 >= 1);
    }

    /**
     *
     * Description : 是否还有下一页.
     *
     * @return
     *
     */
    public boolean isHasNextPage()
    {

        return hasNextPage = (currentPage + 1 <= getTotalPage());
    }

    /**
     *
     * Description : 取得上页的页号, 序号从1开始. 当前页为首页时返回首页序号.
     *
     * @return
     *
     */
    public int getPrePage()
    {
        if (isHasPrePage())
            prePage = currentPage - 1;
        else
            prePage = currentPage;
        return prePage;
    }

    /**
     *
     * Description : 取得下页的页号, 序号从1开始 当前页为尾页时仍返回尾页序号.
     *
     * @return
     *
     */
    public int getNextPage()
    {
        if (isHasNextPage())
            nextPage = currentPage + 1;
        else
            nextPage = currentPage;
        return nextPage;
    }

    public List<T> getResultList()
    {
        return resultList;
    }

    public void setResultList(List<T> resultList)
    {
        this.resultList = resultList;
    }

    public String getResultContent()
    {
        return resultContent;
    }

    public void setResultContent(String resultContent)
    {
        this.resultContent = resultContent;
    }

    /**
     *
     * Description : 获得排序字段,无默认值.多个排序字段时用','分隔
     *
     * @return
     *
     */
    public String getOrderBy()
    {
        return orderBy;
    }

    /**
     *
     * Description : 设置排序字段,多个排序字段时用','分隔.
     *
     * @param orderBy
     *
     */
    public void setOrderBy(final String orderBy)
    {
        this.orderBy = orderBy;
    }

    public Page<T> orderBy(final String theOrderBy)
    {
        setOrderBy(theOrderBy);
        return this;
    }

    /**
     *
     * Description : 获得排序方向
     *
     * @return
     *
     */
    public String getOrder()
    {
        return order;
    }

    /**
     *
     * Description : 设置排序方式向
     *
     * @param order
     *            可选值为desc或asc,多个排序字段时用','分隔.
     *
     */
    public void setOrder(final String order)
    {
        // 检查order字符串的合法值
        String[] orders = StringUtils.split(StringUtils.lowerCase(order), ',');
        for (String orderStr : orders)
        {
            if (!StringUtils.equals(DESC, orderStr)
                    && !StringUtils.equals(ASC, orderStr))
                throw new IllegalArgumentException("排序方向" + orderStr + "不是合法值");
        }

        this.order = StringUtils.lowerCase(order);
    }

    public Page<T> order(final String theOrder)
    {
        setOrder(theOrder);
        return this;
    }

    /**
     *
     * Description : 是否已设置排序字段,无默认值
     *
     * @return
     *
     */
    public boolean isOrderBySetted()
    {
        return (StringUtils.isNotBlank(orderBy) && StringUtils
                .isNotBlank(order));
    }

    /**
     *
     * Description : 查询对象时是否自动另外执行count查询获取总记录数, 默认为 true
     *
     * @return
     *
     */
    public boolean isAutoCount()
    {
        return autoCount;
    }

    public void setAutoCount(final boolean autoCount)
    {
        this.autoCount = autoCount;
    }

    public Page<T> autoCount(final boolean theAutoCount)
    {
        setAutoCount(theAutoCount);
        return this;
    }

    public void setTotalCount(int totalCount)
    {
        this.totalCount = totalCount;
    }

    public void setBeginCount(int beginCount)
    {
        this.beginCount = beginCount;
    }

    public void setPageSize(int pageSize)
    {
        this.pageSize = pageSize;
    }

    public void setHasPrePage(boolean hasPrePage) {
        this.hasPrePage = hasPrePage;
    }

    public void setHasNextPage(boolean hasNextPage) {
        this.hasNextPage = hasNextPage;
    }
}

package com.idoo.iosms.core.utils;

import java.util.Date;

import org.apache.commons.lang.StringUtils;
import org.springframework.util.Assert;


public class PropertyFilter {
    /**
     * 多个属性间OR关系的分隔符.
     */
    public static final String OR_SEPARATOR = "_OR_";

    /**
     * 属性比较类型.
     */
    public enum MatchType {
        EQ, LIKE, LT, GT, LE, GE;
    }

    /**
     * 属性数据类型.
     */
    public enum PropertyType {
        S(String.class), I(Integer.class), L(Long.class), N(Double.class), D(Date.class), B(Boolean.class);

        private Class<?> clazz;

        PropertyType(Class<?> clazz) {
            this.clazz = clazz;
        }

        public Class<?> getValue() {
            return clazz;
        }
    }

    private String[] propertyNames = null;
    private Class<?> propertyType = null;
    private Object propertyValue = null;
    private MatchType matchType = MatchType.EQ;

    public PropertyFilter() {
    }

    /**
     * @param filterName 比较属性字符串,含待比较的比较类型、属性值类型及属性列表.
     *                   eg. LIKES_NAME_OR_LOGIN_NAME
     * @param value 待比较的值.
     */
    public PropertyFilter(final String filterName, final Object value) {

        String matchTypeStr = StringUtils.substringBefore(filterName, "_");
        String matchTypeCode = StringUtils.substring(matchTypeStr, 0, matchTypeStr.length() - 1);
        String propertyTypeCode = StringUtils.substring(matchTypeStr, matchTypeStr.length() - 1, matchTypeStr.length());
        try {
            matchType = Enum.valueOf(MatchType.class, matchTypeCode);
        } catch (RuntimeException e) {
            throw new IllegalArgumentException("filter名称" + filterName + "没有按规则编写,无法得到属性比较类型.", e);
        }

        try {
            propertyType = Enum.valueOf(PropertyType.class, propertyTypeCode).getValue();
        } catch (RuntimeException e) {
            throw new IllegalArgumentException("filter名称" + filterName + "没有按规则编写,无法得到属性值类型.", e);
        }

        String propertyNameStr = StringUtils.substringAfter(filterName, "_");
        propertyNames = StringUtils.split(propertyNameStr, PropertyFilter.OR_SEPARATOR);

        Assert.isTrue(propertyNames.length > 0, "filter名称" + filterName + "没有按规则编写,无法得到属性名称.");
        //按entity property中的类型将字符串转化为实际类型.
        this.propertyValue = ReflectionUtils.convertValue(value, propertyType);
    }

    /**
     * 是否有多个属性.
     */
    public boolean isMultiProperty() {
        return (propertyNames.length > 1);
    }

    /**
     * 获取比较属性名称列表.
     */
    public String[] getPropertyNames() {
        return propertyNames;
    }

    /**
     * 获取唯一的属性名称.
     */
    public String getPropertyName() {
        if (propertyNames.length > 1)
            throw new IllegalArgumentException("There are not only one property");
        return propertyNames[0];
    }

    /**
     * 获取比较值.
     */
    public Object getPropertyValue() {
        return propertyValue;
    }

    /**
     * 获取比较值的类型.
     */
    public Class<?> getPropertyType() {
        return propertyType;
    }

    /**
     * 获取比较类型.
     */
    public MatchType getMatchType() {
        return matchType;
    }
}

0 0
原创粉丝点击