`

HibernateDao.java

阅读更多
/**
 * Copyright (c) 2005-2010 springside.org.cn
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * 
 * $Id: HibernateDao.java 1205 2010-09-09 15:12:17Z calvinxiu $
 */
package com.dao.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.apache.commons.lang.math.NumberUtils;
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.dao.hibernate.PropertyFilter.MatchType;
import com.utils.ReflectionUtils;

/**
 * 封装SpringSide扩展功能的Hibernat DAO泛型基类.
 * 
 * 扩展功能包括分页查询,按属性过滤条件列表查询. 可在Service层直接使用,也可以扩展泛型DAO子类使用,见两个构造函数的注释.
 * 
 * @param <T>
 *            DAO操作的对象类型
 * @param <PK>
 *            主键类型
 * 
 * @author calvin
 */
public class HibernateDao<T, PK extends Serializable> extends
		SimpleHibernateDao<T, PK> {
	/**
	 * 用于Dao层子类的构造函数. 通过子类的泛型定义取得对象类型Class. eg. public class UserDao extends
	 * HibernateDao<User, Long>{ }
	 */
	public HibernateDao() {
		super();
	}

	/**
	 * 用于省略Dao层, Service层直接使用通用HibernateDao的构造函数. 在构造函数中定义对象类型Class. eg.
	 * HibernateDao<User, Long> userDao = new HibernateDao<User,
	 * Long>(sessionFactory, User.class);
	 */
	public HibernateDao(final SessionFactory sessionFactory,
			final Class<T> entityClass) {
		super(sessionFactory, entityClass);
	}

	// -- 分页查询函数 --//

	/**
	 * 分页获取全部对象.
	 */
	public Page<T> getAll(final Page<T> page) {
		return findPage(page);
	}

	/**
	 * 按HQL分页查询.
	 * 
	 * @param page
	 *            分页参数. 注意不支持其中的orderBy参数.
	 * @param hql
	 *            hql语句.
	 * @param values
	 *            数量可变的查询参数,按顺序绑定.
	 * 
	 * @return 分页查询结果, 附带结果列表及所有查询输入参数.
	 */
	public Page<T> findPage(final Page<T> page, final String hql,
			final Object... values) {
		Assert.notNull(page, "page不能为空");

		Query q = createQuery(hql, values);

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

		setPageParameterToQuery(q, page);

		List result = q.list();
		page.setResult(result);
		return page;
	}

	/**
	 * 按HQL分页查询.
	 * 
	 * @param page
	 *            分页参数. 注意不支持其中的orderBy参数.
	 * @param hql
	 *            hql语句.
	 * @param values
	 *            命名参数,按名称绑定.
	 * 
	 * @return 分页查询结果, 附带结果列表及所有查询输入参数.
	 */
	@SuppressWarnings("unchecked")
	public Page<T> findPage(final Page<T> page, final String hql,
			final Map<String, ?> values) {
		Assert.notNull(page, "page不能为空");

		Query q = createQuery(hql, values);

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

		setPageParameterToQuery(q, page);

		List result = q.list();
		page.setResult(result);
		return page;
	}

	/**
	 * 按Criteria分页查询.
	 * 
	 * @param page
	 *            分页参数.
	 * @param criterions
	 *            数量可变的Criterion.
	 * 
	 * @return 分页查询结果.附带结果列表及所有查询输入参数.
	 */
	@SuppressWarnings("unchecked")
	public Page<T> findPage(final Page<T> page, final Criterion... criterions) {
		Assert.notNull(page, "page不能为空");

		Criteria c = createCriteria(criterions);

		if (page.isAutoCount()) {
			long totalCount = countCriteriaResult(c);
			page.setTotalCount(totalCount);
		}
		
		if(page.getPageNo() > page.getTotalPages()) {
			page.setPageNo(NumberUtils.toInt(Long.toString(page.getTotalPages())));
		}
		
		setPageParameterToCriteria(c, page);

		List result = c.list();
		page.setResult(result);
		return page;
	}

	/**
	 * 设置分页参数到Query对象,辅助函数.
	 */
	protected Query setPageParameterToQuery(final Query q, final Page<T> page) {

		Assert.isTrue(page.getPageSize() > 0, "Page Size must larger than zero");

		// hibernate的firstResult的序号从0开始
		q.setFirstResult(page.getFirst() - 1);
		q.setMaxResults(page.getPageSize());
		return q;
	}

	/**
	 * 设置分页参数到Criteria对象,辅助函数.
	 */
	protected Criteria setPageParameterToCriteria(final Criteria c,
			final Page<T> page) {

		Assert.isTrue(page.getPageSize() > 0, "Page Size must larger than zero");

		// hibernate的firstResult的序号从0开始
		c.setFirstResult(page.getFirst() - 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;
	}

	/**
	 * 执行count查询获得本次Hql查询所能获得的对象总数.
	 * 
	 * 本函数只能自动处理简单的hql语句,复杂的hql查询请另行编写count语句查询.
	 */
	protected long countHqlResult(final String hql, final Object... values) {
		String countHql = prepareCountHql(hql);

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

	/**
	 * 执行count查询获得本次Hql查询所能获得的对象总数.
	 * 
	 * 本函数只能自动处理简单的hql语句,复杂的hql查询请另行编写count语句查询.
	 */
	protected long countHqlResult(final String hql, final Map<String, ?> values) {
		String countHql = prepareCountHql(hql);

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

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

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

	/**
	 * 执行count查询获得本次Criteria查询所能获得的对象总数.
	 */
	@SuppressWarnings("unchecked")
	protected long countCriteriaResult(final 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) ReflectionUtils.getFieldValue(impl,
					"orderEntries");
			ReflectionUtils
					.setFieldValue(impl, "orderEntries", new ArrayList());
		} catch (Exception e) {
			logger.error("不可能抛出的异常:{}", e.getMessage());
		}

		// 执行Count查询
		Long totalCountObject = Long.parseLong(c
				.setProjection(Projections.rowCount()).uniqueResult()
				.toString());
		long totalCount = (totalCountObject != null) ? totalCountObject : 0;

		// 将之前的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;
	}

	// -- 属性过滤条件(PropertyFilter)查询函数 --//

	/**
	 * 按属性查找对象列表,支持多种匹配方式.
	 * 
	 * @param matchType
	 *            匹配方式,目前支持的取值见PropertyFilter的MatcheType enum.
	 */
	public List<T> findBy(final String propertyName, final Object value,
			final MatchType matchType) {
		Criterion criterion = buildCriterion(propertyName, value, matchType);
		return find(criterion);
	}

	/**
	 * 按属性过滤条件列表查找对象列表.
	 */
	public List<T> find(List<PropertyFilter> filters) {
		Criterion[] criterions = buildCriterionByPropertyFilter(filters);
		return find(criterions);
	}

	/**
	 * 按属性过滤条件列表分页查找对象.
	 */
	public Page<T> findPage(final Page<T> page,
			final List<PropertyFilter> filters) {
		Criterion[] criterions = buildCriterionByPropertyFilter(filters);
		return findPage(page, criterions);
	}

	/**
	 * 按属性条件参数创建Criterion,辅助函数.
	 */
	protected Criterion buildCriterion(final String propertyName,
			final Object propertyValue, final MatchType matchType) {
		Assert.hasText(propertyName, "propertyName不能为空");
		Criterion criterion = null;
		// 根据MatchType构造criterion
		switch (matchType) {
		case EQ:
			criterion = Restrictions.eq(propertyName, propertyValue);
			break;
		case LIKE:
			criterion = Restrictions.like(propertyName, (String) propertyValue,
					MatchMode.ANYWHERE);
			break;

		case LE:
			criterion = Restrictions.le(propertyName, propertyValue);
			break;
		case LT:
			criterion = Restrictions.lt(propertyName, propertyValue);
			break;
		case GE:
			criterion = Restrictions.ge(propertyName, propertyValue);
			break;
		case GT:
			criterion = Restrictions.gt(propertyName, propertyValue);
		}
		return criterion;
	}

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

分享到:
评论
4 楼 li1045460568 2015-09-07  
3 楼 li1045460568 2015-09-07  
[flash=200,200]
[flash=200,200][url][img][list]
[*]
[b][i][u]
引用
[/u][/i][/b]
[/list][/img][/url][/flash]
[/flas[color=darkred][/color]   h]
2 楼 jie66989 2012-07-27  
主要就是这个类了,这是前段时间学习的时候用的一部分,那个时候只是想着自己用,没有分享的意识。下次上网的时候一定把剩下的打包发上来
1 楼 zhongaili520 2012-07-20  
能把全部的都上吗

相关推荐

    DmDialect-for-hibernate4.0.zip

    Hibernate是一个强大的ORM(对象关系映射)框架,它允许开发者用面向对象的方式处理数据库,将Java对象与数据库表之间的映射关系自动化。Dialect在Hibernate中起着至关重要的作用,它定义了特定数据库的SQL语法、...

    springmvc, spring5.x , hibernate5.x 整合

    Hibernate 5.x则是Java世界中流行的持久化框架,它简化了数据库操作,通过对象关系映射(ORM)将Java对象与数据库表进行映射。Hibernate 5.x引入了新的特性,如对JPA 2.2的支持,提升了性能,并提供了更好的错误信息...

    HibernateDao

    hibernateDao工具类

    dao.rar_dao

    在这个"dao.rar_dao"的压缩包中,包含了一系列与DAO相关的Java源代码文件,它们分别是ItemDAO.java、ClassDAO.java、LoginDAO.java、GoodsCar.java和GoodsDAO.java。现在,我们将详细讨论这些文件可能涉及的知识点。...

    dao.zip_dao_java dao_java数据库连接_struts_struts dao

    2. 实现该接口的具体类,这个类将包含与数据库交互的逻辑,使用JDBC(Java Database Connectivity)或者其他ORM(Object-Relational Mapping)框架如Hibernate或MyBatis。 3. 在业务逻辑层,通过依赖注入或者工厂...

    hibernate封装.pdf

    在提供的代码片段中,我们可以看到一个`HibernateDao`类,它是对Hibernate的一些基本操作进行了封装,包括获取、删除等方法。下面将详细解释这些知识点。 1. **SessionFactory**: `SessionFactory`是Hibernate的...

    JavaEE spring和Hibernate整合(有hibernate.cfg.xml)

    在Java企业级开发中,Spring框架和Hibernate框架的整合是常见的技术栈选择,它们能够帮助开发者构建高效、灵活且易于维护的后端系统。本文将深入探讨如何在JavaEE项目中整合Spring和Hibernate,以及hibernate.cfg....

    Java.Persistence.with.Hibernate.2nd.Edition

    design patterns that are used with Hibernate, such as the Data Access Object (DAO). You see how you can test your Hibernate application easily and learn what other best practices are relevant if you ...

    Flex+J2EE实例(cairngorm+blazeDS+hibernate+spring) part3.pdf

    其中一个重要的文件是`HibernateDao.java`,该文件提供了一组通用的数据库操作方法,如下所示: ```java package com.core.hibernate; import java.io.Serializable; import java.util.List; import org....

    使用Struts.DAO.Hibernate完成用户登陆

    在Java Web开发中,Struts、DAO(Data Access Object)模式和Hibernate是常见的技术栈,它们各自承担着不同的职责,协同工作以实现高效的数据访问和业务处理。本篇将详细介绍如何利用这三种技术来实现用户登录功能。...

    HibernateDao 通用

    在Java开发中,HibernateDao 通常作为一个独立的层,位于业务逻辑层(Service Layer)与持久化层(Persistence Layer)之间,用来封装对数据库的一系列CRUD(创建、读取、更新、删除)操作。 在JUMPER小组的工作...

    JDBC_DAO.rar

    在IT行业中,数据库访问是应用程序开发中的核心部分。...同时,随着ORM(对象关系映射)框架如Hibernate和MyBatis的普及,虽然直接使用JDBC编写DAO的方式逐渐减少,但理解JDBC DAO仍然是每个Java开发者必备的基础知识。

    Manning.Java.Persistence.with.Hibernate.Nov.2006

    《Java Persistence with Hibernate》是Manning出版社在2006年11月出版的一本专业书籍,专注于Java领域的持久化技术,尤其是Hibernate框架的应用。这本书深入探讨了如何使用Hibernate来处理Java应用程序中的对象关系...

    hibernate dao 生成工具

    Hibernate DAO(Data Access Object)生成工具是用于自动化创建数据访问层对象的实用程序,它可以显著提高开发效率,尤其是在处理大量数据库交互的项目中。DAO模式是一种设计模式,它提供了对数据库操作的抽象,使得...

    使用模式设计及java5新特性在HibernateDAO中的应用

    标题 "使用模式设计及java5新特性在HibernateDAO中的应用" 涉及到的是软件开发中的两个关键领域:设计模式和Java编程语言的新特性,特别是在数据访问对象(DAO)层如何结合使用它们。这篇文章可能详细阐述了如何利用...

    王者归来之达内内部绝密Hibernate课件.doc

    Hibernate是一款流行的ORM(Object-Relational Mapping)工具,它充当了Java应用程序与关系数据库之间的桥梁,简化了数据操作。以下是基于课件内容提炼出的关键知识点: 1. **Hibernate概览**: - Hibernate是一种...

    开发Spring.Struts.Hibernate应用.

    在IT行业中,Spring、Struts和Hibernate是三个非常重要的Java Web开发框架,它们共同构建了企业级应用的基础架构。Spring提供了全面的后端服务管理,Struts则专注于 MVC(Model-View-Controller)架构的实现,而...

    HibernateDAO的写法

    通过以上分析,我们可以看到,HibernateDAO的写法涉及到了面向对象设计原则、事务管理、数据库操作等多个方面,理解和掌握这些知识点,对于提升Java企业级应用的开发效率和质量至关重要。在实际开发中,我们需要根据...

Global site tag (gtag.js) - Google Analytics