加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

HibernateDao.java

发布时间:2020-12-15 03:17:17 所属栏目:Java 来源:网络整理
导读:今天PHP站长网 52php.cn把收集自互联网的代码分享给大家,仅供参考。 /** * Copyright (c) 2005-2010 springside.org.cn * * Licensed under the Apache License,Version 2.0 (the "License"); * * $Id: HibernateDao.jav

以下代码由PHP站长网 52php.cn收集自互联网

现在PHP站长网小编把它分享给大家,仅供参考

/**

 * 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 Map<String,?> values) {

 Assert.notNull(page,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,"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语句,?> values) {

 String countHql = prepareCountHql(hql);


 try {

 Long count = findUnique(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);

 } 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.getMatchType());

 disjunction.add(criterion);

 }

 criterionList.add(disjunction);

 }

 }

 return criterionList.toArray(new Criterion[criterionList.size()]);

 }

}




以上内容由PHP站长网【52php.cn】收集整理供大家参考研究

如果以上内容对您有帮助,欢迎收藏、点赞、推荐、分享。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读