`
清晨阳光
  • 浏览: 39543 次
  • 性别: Icon_minigender_1
  • 来自: 西安
社区版块
存档分类
最新评论

发一个Hibernate工具类

阅读更多

为了简化分页查询的条件参数,写了一个工具类。

前提是,页面的参数命名必须按照一定规则,这个规则是f_dataType_property以及s_sortType_property。

f_前缀代表这是一个过滤器(filter),s_前缀代表这是一个排序器(Sort)。

dataType是数据类型,可以写一个枚举来定义这些类型,sortType是排序类型,也可以写一个枚举来定义。

接下来,页面提交到类里面的时候,需要用一个类的静态方法来处理并解析提交的参数。

Map<String, String> parametersMap = org.springframework.web.util.WebUtils.getParametersStartingWith(request, prefix);

prefix就是前缀,根据f_前缀以及s_前缀,就可以拿到过滤器以及排序器的Map集合

然后,

SimpleFilter simpleFilter = new SimpleFilter();

for (Map.Entry<String, String> entry : parametersMap.entrySet()) {

  // 添加过滤器,这行添加过滤器仅作为一个例子,实际上并不正确,还需要根据dataType来转换value的值类型

  // 并且key也有可能需要添加级联处理

  simpleFilter.addFilter(entry.getKey(), entry.getValue(), MatchType.EQ);

}

最后,只需要xxxDao.findCount(simpleFilter); Collection<xxx> items = xxxDao.find(simpleFilter);

这样就可以得到结果集的数目以及结果集数组

然后可以方便的在页面展示出来。

仅将SimpleFilter的代码贴出来:

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.commons.lang.StringUtils;
import org.hibernate.Criteria;
import org.hibernate.criterion.Disjunction;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Restrictions;

/**
 * 属性过滤器
 * 
 */
public class SimpleFilter {

	private List<Filter> filters = new ArrayList<Filter>();
	private Set<String> alias = new HashSet<String>(); // 防止重复添加alias用

	public boolean hasFilters() {
		return filters.size() > 0;
	}

	public void addFilter(final String property, final Object value, final MatchType matchType) {
		if (matchType == MatchType.OR || matchType == MatchType.BETWEEN) {
			throw new RuntimeException("匹配模式不正确");
		} else {
			filters.add(new Filter(property, value, matchType));
		}
	}

	public void addFilter(final String property, final Object value) {
		filters.add(new Filter(property, value));
	}

	public void addFilter(final String property, final Object lo, final Object hi) {
		filters.add(new Filter(property, lo, hi));
	}

	public void addFilter(final Set<OrClausePair> set) {
		filters.add(new Filter(set));
	}

	/**
	 * 清理过滤器
	 * 在具有级联条件的查询中,alias不能重复添加,只允许添加一次
	 * 在执行完一次count(*)查询后,之前添加的criteria全部失效
	 * 重新添加criteria的时候,需要清空alias的Set集合
	 * 以便正确执行createAlias语句
	 * 
	 */
	public void clearFilter() {
		alias.clear();
	}

	/**
	 * 构建当前filter的Criteria对象
	 */
	public Criteria buildCriteria(final Criteria criteria) {
		for (Filter filter : filters) {
			if (filter.getMatchType() == MatchType.BETWEEN) {
				buildCriteria(criteria, filter.getProperty(), filter.getLo(), filter.getHi());
			} else if (filter.getMatchType() == MatchType.OR) {
				builCriteria(criteria, filter.getSet());
			} else {
				buildCriteria(criteria, filter.getProperty(), filter.getValue(), filter.getMatchType());
			}
		}
		return criteria;
	}

	/**
	 * 根据多个属性名、值和匹配类型构建Hibernate的Criteria的OR对象
	 */
	private Criteria builCriteria(final Criteria criteria, final Set<OrClausePair> set) {
		Disjunction disjunction = Restrictions.disjunction();
		for (OrClausePair pair : set) {
			String alias = createAlias(criteria, pair.getProperty());
			if (StringUtils.isNotBlank(alias)) {
				MatchType matchType = pair.getMatchType();
				if (matchType == MatchType.BETWEEN) {
					if (pair.getLo() != null && pair.getHi() != null) {
						disjunction.add(Restrictions.between(alias, pair.getLo(), pair.getHi()));
					}
				} else {
					switch (matchType) {
					case NULL:
						disjunction.add(Restrictions.isNull(alias));
						break;
					case NOTNULL:
						disjunction.add(Restrictions.isNotNull(alias));
						break;
					case EMPTY:
						disjunction.add(Restrictions.isEmpty(alias));
						break;
					case NOTEMPTY:
						disjunction.add(Restrictions.isNotEmpty(alias));
						break;
					}
					Object value = pair.getValue();
					if (value != null) {
						switch (matchType) {
						case EQ:
							disjunction.add(Restrictions.eq(alias, value));
							break;
						case LIKE:
							disjunction.add(Restrictions.like(alias, (String) value, MatchMode.ANYWHERE));
							break;
						case LIKESTART:
							disjunction.add(Restrictions.like(alias, (String) value, MatchMode.START));
							break;
						case LIKEND:
							disjunction.add(Restrictions.like(alias, (String) value, MatchMode.END));
							break;
						case LE:
							disjunction.add(Restrictions.le(alias, value));
							break;
						case LT:
							disjunction.add(Restrictions.lt(alias, value));
							break;
						case GE:
							disjunction.add(Restrictions.ge(alias, value));
							break;
						case GT:
							disjunction.add(Restrictions.gt(alias, value));
							break;
						case NE:
							disjunction.add(Restrictions.ne(alias, value));
							break;
						}
					}
				}
			}
		}
		criteria.add(disjunction);
		return criteria;
	}

	/**
	 * 根据属性名、值和匹配类型构建Hibernate的Criteria对象
	 */
	private Criteria buildCriteria(final Criteria criteria, final String property, final Object value,
			final MatchType matchType) {
		String alias = createAlias(criteria, property);
		if (StringUtils.isNotBlank(alias)) {
			switch (matchType) {
			case NULL:
				Restrictions.isNull(alias);
				return criteria;
			case NOTNULL:
				Restrictions.isNotNull(alias);
				return criteria;
			case EMPTY:
				Restrictions.isEmpty(alias);
				return criteria;
			case NOTEMPTY:
				Restrictions.isNotEmpty(alias);
				return criteria;
			}
			if (value != null) {
				switch (matchType) {
				case EQ:
					criteria.add(Restrictions.eq(alias, value));
					break;
				case LIKE:
					criteria.add(Restrictions.like(alias, (String) value, MatchMode.ANYWHERE));
					break;
				case LIKESTART:
					criteria.add(Restrictions.like(alias, (String) value, MatchMode.START));
					break;
				case LIKEND:
					criteria.add(Restrictions.like(alias, (String) value, MatchMode.END));
					break;
				case LE:
					criteria.add(Restrictions.le(alias, value));
					break;
				case LT:
					criteria.add(Restrictions.lt(alias, value));
					break;
				case GE:
					criteria.add(Restrictions.ge(alias, value));
					break;
				case GT:
					criteria.add(Restrictions.gt(alias, value));
					break;
				case NE:
					criteria.add(Restrictions.ne(alias, value));
					break;
				}
			}
		}
		return criteria;
	}

	/**
	 * 创建BETWEEN匹配类型的Criteria对象
	 */
	private Criteria buildCriteria(final Criteria criteria, final String property, final Object lo, final Object hi) {
		String alias = createAlias(criteria, property);
		if (StringUtils.isNotBlank(alias) && lo != null && hi != null) {
			criteria.add(Restrictions.between(alias, lo, hi));
		}
		return criteria;
	}

	/**
	 * 为Criteria对象添加别名
	 * 最多支持2级级联,例如animal.pet.cat
	 * @param criteria Criteria对象
	 * @param property 属性
	 * @return 别名
	 */
	private String createAlias(final Criteria criteria, final String property) {
		String[] names = StringUtils.split(property, ".");
		if (names != null && names.length == 2) {
			if (alias.add(names[0])) {
				criteria.createAlias(names[0], names[0]);
			}
			return names[0] + "." + names[1];
		} else if (names != null && names.length == 3) {
			if (alias.add(names[0])) {
				criteria.createAlias(names[0], names[0]);
			}
			if (alias.add(names[0] + "." + names[1])) {
				criteria.createAlias(names[0] + "." + names[1], names[1]);
			}
			return names[1] + "." + names[2];
		} else {
			return property;
		}
	}

	/**
	 * 过滤器
	 * 两个参数的构造方法,默认查询条件为LIKE
	 */
	private static class Filter {
		private String property;
		private Object value;
		private Object lo;
		private Object hi;
		private Set<OrClausePair> set;
		private MatchType matchType;

		/**
		 * 构造一个OR条件的过滤器,使用disjunction进行连接
		 * @param set OR条件参数集合
		 */
		public Filter(Set<OrClausePair> set) {
			this.set = set;
			this.matchType = MatchType.OR;
		}

		/**
		 * 构造LIKE类型查询
		 * @param property 属性
		 * @param value 值
		 */
		public Filter(String property, Object value) {
			this.property = property;
			this.value = value;
			this.matchType = MatchType.LIKE;
		}

		/**
		 * 构造MatchType类型的查询
		 * @param property 属性
		 * @param value 值
		 * @param matchType 匹配类型
		 */
		public Filter(String property, Object value, MatchType matchType) {
			this.property = property;
			this.value = value;
			this.matchType = matchType;
		}

		/**
		 * 构造Between类型的查询
		 * @param property 属性
		 * @param lo lowValue
		 * @param hi hiValue
		 */
		public Filter(String property, Object lo, Object hi) {
			this.property = property;
			this.lo = lo;
			this.hi = hi;
			this.matchType = MatchType.BETWEEN;
		}

		public String getProperty() {
			return property;
		}

		public Object getValue() {
			return value;
		}

		public Object getLo() {
			return lo;
		}

		public Object getHi() {
			return hi;
		}

		public Set<OrClausePair> getSet() {
			return set;
		}

		public MatchType getMatchType() {
			return matchType;
		}
	}
}

上述过滤器参考自Jmesa源码的一个过滤器,有兴趣的同学可以研究一下Jmesa的源码。Jmesa的TableFacade.getLimit().getSortSet().getSorts()可以拿到页面的所有排序集合,而TableFacade.getLimit().getFilterSet().getFilters()则取得所有过滤对象。

接下来,使用SimpleFilter,并配合通用Hibernate泛型DAO,就可以很方便的处理页面表格了。

 

补充两个类:

 

public enum MatchType {
	EQ, LIKE, LIKESTART, LIKEND, LT, GT, LE, GE, BETWEEN, NE, OR, NULL, NOTNULL, EMPTY, NOTEMPTY;
}
 
import org.hibernate.criterion.Criterion;
/**
 * 用于为SimpleFilter添加OR过滤条件
 *
 */
public class OrClausePair {

	private String property;
	private Object value;
	private Object lo;
	private Object hi;
	private MatchType matchType;
	private Criterion criterion;

	public OrClausePair(String property, Object value, MatchType matchType) {
		if (matchType == MatchType.BETWEEN) {
			throw new RuntimeException("匹配模式不正确");
		} else {
			this.property = property;
			this.value = value;
			this.matchType = matchType;
		}
	}

	public OrClausePair(String property, Object lo, Object hi) {
		this.property = property;
		this.lo = lo;
		this.hi = hi;
		this.matchType = MatchType.BETWEEN;
	}

	public OrClausePair(Criterion criterion) {
		this.criterion = criterion;
	}

	public String getProperty() {
		return property;
	}

	public Object getValue() {
		return value;
	}

	public Object getLo() {
		return lo;
	}

	public Object getHi() {
		return hi;
	}

	public MatchType getMatchType() {
		return matchType;
	}

	public Criterion getCriterion() {
		return criterion;
	}

}
 

 

分享到:
评论
8 楼 mib168 2010-12-28  
楼主能不能给总结下Criteria和HQL平时项目中都应用于什么情况下呢?  用Criteria比较少 呵呵
7 楼 ycyangcai 2010-12-24  
很不错,不知道相关的类能否提供。你说你参照springside的,但发现你的比springside更强大!
6 楼 wenxiang_tune 2010-11-25  
所以我们需要一个更好的分页插件,我对自己现在的分页设计不太满意,各位有没更好建议?
5 楼 清晨阳光 2010-03-04  
如果你的系统有大量的表格都需要分页,并且都是符合条件查询的,那么SQL拼接的数量是惊人的!
4 楼 peak 2010-03-03  
这个写的不错,可惜啊,我觉得还是用sql拼凑出来的好
3 楼 清晨阳光 2010-03-03  
这个仿了一部分SpringSide
2 楼 mxdba321123 2010-03-02  
貌似类似的工具类 在springside和rapidframework等框架里都有,呵呵
1 楼 whaosoft 2010-03-02  
     嗯 拿走了 这个写的还是挺不错 挺全面的 感谢之

相关推荐

    hibernate的大部分的工具类

    首先,让我们深入了解一下Hibernate工具类的重要性。在进行数据库操作时,开发人员经常需要执行一些通用的任务,例如创建会话工厂、打开和关闭数据库连接、管理事务等。Hibernate工具类可以提供这些功能的封装,减少...

    hibernate工具类大全

    这个“Hibernate工具类大全”压缩包包含了一系列资源,可以帮助开发者更高效地搭建和使用Hibernate框架。以下是对这些资源的详细解释: 1. **jar包**: Hibernate的核心功能依赖于一组jar包,包括`hibernate-core....

    Hibernate工具类

    Hibernate是一个非常流行的Java ORM(对象关系映射)框架,它允许开发人员使用面向对象的方式来操作数据库,而无需直接编写SQL语句。在Java应用中,使用Hibernate可以极大地提高开发效率,同时减少出错的可能性。`...

    Spring+Hibernate工具类所有增删改查

    标题"Spring+Hibernate工具类所有增删改查"暗示了这是一个集合了Spring和Hibernate框架中用于基本数据库操作的工具类库。这些工具类通常包含了一系列静态方法,用于执行常见的数据库CRUD(创建、读取、更新、删除)...

    封装了一个Hibernate增删改查的工具类

    本篇将详细介绍一个基于Hibernate封装的增删改查工具类,该工具类整合了util、comm.util以及beanutils等库,旨在提高开发效率,降低代码复杂度,方便开发者快速地获取session和sessionFactory。 首先,让我们理解...

    超好用的hibernate查询工具类

    本篇将详细讲解一个“超好用的Hibernate查询工具类”,以及如何利用它来提升开发效率。 首先,我们需要理解Hibernate的基本概念。Hibernate是一种持久化框架,它可以将Java对象映射到数据库表,从而避免了编写大量...

    hibernate工具类

    hibernate开发的工具类,封装的sessionFactory,session等

    hibernate5类包

    Hibernate 5 是一个开源的对象关系映射(ORM)框架,它允许Java开发人员在数据库上操作对象,而无需编写大量的SQL代码。这个“hibernate5类包”包含了Hibernate 5.2.11.Final版本的所有核心组件和其他相关模块,使得...

    hibernate hql where语句拼接工具类

    在Java开发中,Hibernate是一个非常流行的ORM(对象关系映射)框架,它允许开发者使用面向对象的方式来操作数据库。HQL(Hibernate Query Language)是Hibernate提供的一个SQL的面向对象的查询语言,它使得开发者...

    hibernate的第一个例子

    **描述分析:**描述提到这是一个超级简单的例子,包含一个持久化对象(通常是Java类,对应数据库中的表)、一个辅助类(可能是配置或者工具类,帮助操作数据库)以及一个测试类(用于验证代码功能)。这个例子特别...

    根据hibernate.cfg.xml文件生成POJO数据库表的工具类

    在Java的Web开发中,Hibernate是一个非常流行的ORM(对象关系映射)框架,它使得开发者可以使用面向对象的方式来操作数据库,而无需关心底层SQL的细节。`hibernate.cfg.xml`是Hibernate配置文件,用于定义数据库连接...

    生成hibernate实体类

    2. **引入Hibernate工具**:Hibernate提供了一个名为`hibernatetool`的命令行工具,或者可以通过IDE插件(如Eclipse或IntelliJ IDEA的Hibernate插件)来实现实体类的自动生成。你需要在项目中添加Hibernate的相关...

    hibernate 开发工具包

    在给定的“hibernate 开发工具包”中,包含的是Hibernate 3.3.2版本的jar包,这是一个相对较为早期但仍然被一些项目使用的版本。以下是关于Hibernate 3.3.2及其关键特性的详细解释: 1. **对象关系映射(ORM)**:...

    菜鸟快速运行第一个hibernate

    标题“菜鸟快速运行第一个hibernate”表明了这是一个针对初学者的教程,旨在帮助他们快速上手并成功运行他们的第一个Hibernate项目。Hibernate是一个强大的Java ORM(对象关系映射)框架,它简化了数据库操作,使得...

    hibernate+spring配置文件

    - **实体类映射文件(.hbm.xml)**:每个实体类对应一个映射文件,定义了表结构、字段映射、主键生成策略等。 3. **事务管理**: - Spring支持编程式和声明式事务管理。在Spring配置文件中,需要开启事务管理器,...

    用Hibernate自带的工具生成映射文件

    描述中的博文链接指向了一个名为“yefeishan”的作者在ITEYE博客上的文章,虽然具体内容无法在这里详述,但通常这类文章会详细介绍如何配置和使用Hibernate Tools,包括安装、设置IDE集成、配置Hibernate工具、运行...

Global site tag (gtag.js) - Google Analytics