- 浏览: 118591 次
- 性别:
- 来自: 深圳
文章分类
最新评论
-
IAmMrLi:
...
基于HIBERNATE的全自动查询框架(二) -
ganbo:
...
基于HIBERNATE的全自动查询框架(二) -
ganbo:
...
基于HIBERNATE的全自动查询框架(二) -
wanbing1986:
给我一份借鉴下wanbing1986@126.com,谢谢
基于HIBERNATE的全自动查询框架(一) -
Cynthia9023:
博主我也没有权限下载 能否也发我一份?jane9023@163 ...
基于HIBERNATE的全自动查询框架(一)
这是全自动查框架最后一篇,主要讲解上一篇中最后提到的各种类型的值的处理器,这些处理器最终将:
对字符串继使用LIKE关键字,
对日期分拆成两个日期:当天的0时0分0秒和23时59分59秒,使用>=日期1并且<=日期二
对两个日期,直接使用>=日期1并且<=日期二
对单个数字,使用=
对两个数字,使用>=日期1并且<=日期二
对于其它类其它类型,如Boolean使用=
生成最终HIBERNATE能接受的Criterion对象。类图如下
接口的完成代码
抽象类代码如下
主要的逻辑其实就在于上面这个抽象类,具体子类的代码一般很少,下面首先是处理字符串类型的子类的代码:
处理整形数字的类
其它如长整型,浮点型的代码都差一多,只有处理日期的比较复杂,要分析不同格式的日期,并决定是否将一个值拆分成两个,下面是TimeStampValueHandler类的代码
其它类型的日期是委托此类完成的,如处理java.util.date类型条件的类代码
对字符串继使用LIKE关键字,
对日期分拆成两个日期:当天的0时0分0秒和23时59分59秒,使用>=日期1并且<=日期二
对两个日期,直接使用>=日期1并且<=日期二
对单个数字,使用=
对两个数字,使用>=日期1并且<=日期二
对于其它类其它类型,如Boolean使用=
生成最终HIBERNATE能接受的Criterion对象。类图如下
接口的完成代码
package com.esc.common.util.conditionbuilder.valuehandler; import java.util.List; import org.hibernate.criterion.Criterion; import com.esc.common.util.Condition; /** * 条件处理器接口 */ public interface IValueHandler { /** * 把condition对象转换Hibernate能识别的条件对象 * @param conditios * @param alias * @return */ List<Criterion> getConditions(List<Condition> conditios, String alias); /** * 获得本处理器能处理的属性类型 * @return 本处理器能处理的属性类型 */ Class getDealType(); }
抽象类代码如下
package com.esc.common.util.conditionbuilder.valuehandler; import java.util.ArrayList; import java.util.List; import org.hibernate.criterion.Criterion; import org.hibernate.criterion.Expression; import org.hibernate.criterion.MatchMode; import com.esc.common.util.Condition; import com.esc.common.util.DetachedCriteriaUtil; import com.esc.common.util.Operator; /** * 拼条件基类 */ public abstract class AbstractValueHandler implements IValueHandler { //取得别名 private String getColumnAlia(String columName,String alias){ if(columName.contains(".")){ return DetachedCriteriaUtil.getAliasFromPropertyChainString(columName); } return new StringBuffer().append(alias).append(".").append(columName).toString(); } //构造=条件 protected Criterion eq(String key, Object value, String alias) { return Expression.eq(getColumnAlia(key,alias), value); } //构造<=条件 protected Criterion le(String key, Object value, String alias) { return Expression.le(getColumnAlia(key,alias), value); } //>= protected Criterion ge(String key, Object value, String alias) { return Expression.ge(getColumnAlia(key,alias), value); } //< protected Criterion lt(String key, Object value, String alias) { return Expression.lt(getColumnAlia(key,alias), value); } //> protected Criterion gt(String key, Object value, String alias) { return Expression.gt(getColumnAlia(key,alias), value); } //like protected Criterion like(String key, Object value, String alias) { return Expression.like(getColumnAlia(key,alias), value.toString(),MatchMode.ANYWHERE).ignoreCase(); } /** * 抽象类已实现了接口的第一个方法 * 真正拼条件的方法 * @param conditios */ @Override public List<Criterion> getConditions(List<Condition> conditios,String alias) { //第一步调用具体子类,子类先把条件值从字符串转换成各种类型的值,把一个日期分拆成两个日期等,是由具体子类做的事 beforeDoAdd(conditios); //子类把结果放回到集合,这里可以循环的取出单个Condition对象,生成Criterion对象了 List<Criterion> result = new ArrayList<Criterion>(conditios.size()); if (conditios.size() == 1) {//单条件 Condition condition = conditios.get(0); if(condition.getValue() instanceof String){//处理字符串,目前字符串只支持单条件,即不支持 like xxx or like yyy result.add(like(condition.getProperty(), condition.getValue(),alias)); }else{//处理其它类型 if (Operator.EQ.equals(condition.getOperator())){ result.add(eq(condition.getProperty(), condition.getValue(),alias)); } else if (Operator.GT.equals(condition.getOperator())) { result.add(gt(condition.getProperty(), condition.getValue(),alias)); } else if (Operator.LE.equals(condition.getOperator())) { result.add(le(condition.getProperty(), condition.getValue(),alias)); } else if (Operator.LT.equals(condition.getOperator())) { result.add(lt(condition.getProperty(), condition.getValue(),alias)); } else if (Operator.GE.equals(condition.getOperator())) { result.add(ge(condition.getProperty(), condition.getValue(),alias)); } } } else {//多条件,如 aaa < x < bbb for (Condition condition : conditios) { if (Operator.GE.equals(condition.getOperator())) { result.add(ge(condition.getProperty(), condition.getValue(),alias)); } else if (Operator.GT.equals(condition.getOperator())) { result.add(gt(condition.getProperty(), condition.getValue(),alias)); } else if (Operator.LE.equals(condition.getOperator())) { result.add(le(condition.getProperty(), condition.getValue(),alias)); } else if (Operator.LT.equals(condition.getOperator())) { result.add(lt(condition.getProperty(), condition.getValue(),alias)); } } } return result; } /** * 此方法主要是把Condition中的VALUE值转成所需类型,修正日期格式和时间值,把一个日期分拆成两个日期等 * @param conditios */ protected abstract void beforeDoAdd(List<Condition> conditios); @Override public boolean equals(Object obj) { if(!(obj instanceof IValueHandler)) return false; return ((IValueHandler)obj).getDealType().getName().equals(getDealType().getName()); } @Override public int hashCode() { return getDealType().getName().hashCode(); } protected int getYearFromDateString(String dateString){ return Integer.valueOf(dateString.substring(0,4)); } protected int getMonthFromDateString(String dateString){ return Integer.valueOf(dateString.substring(4,6)); } protected int getDayFromDateString(String dateString){ return Integer.valueOf(dateString.substring(6,8)); } }
主要的逻辑其实就在于上面这个抽象类,具体子类的代码一般很少,下面首先是处理字符串类型的子类的代码:
package com.esc.common.util.conditionbuilder.valuehandler; import java.util.List; import com.esc.common.util.Condition; public class StringValueHandler extends AbstractValueHandler { private static StringValueHandler stringConditionDealer = new StringValueHandler(); private StringValueHandler(){ super(); } //实现父类定义的回调方法,在父类拼条件前将条件值中的空格替换成%, @Override protected void beforeDoAdd(List<Condition> conditios) { Condition condition = conditios.get(0); condition.setValue(condition.getValue().toString().replaceAll(" ", "%")); } //返回本类所能处理的条件类型 @Override public Class getDealType() { return String.class; } public static IValueHandler getInstance() { return stringConditionDealer; } }
处理整形数字的类
package com.esc.common.util.conditionbuilder.valuehandler; import java.util.List; import com.esc.common.util.Condition; public class IntegerValueHandler extends AbstractValueHandler { private static IntegerValueHandler integerConditionDealer = new IntegerValueHandler(); private IntegerValueHandler(){ super(); } public static IValueHandler getInstance() { return integerConditionDealer; } //将字符串传换成整形数字 @Override public void beforeDoAdd(List<Condition> conditios) { for (Condition condition : conditios) { condition.setValue(new Integer(condition.getValue().toString())); } } //本类处理整形条件 @Override public Class getDealType() { return Integer.class; } }
其它如长整型,浮点型的代码都差一多,只有处理日期的比较复杂,要分析不同格式的日期,并决定是否将一个值拆分成两个,下面是TimeStampValueHandler类的代码
package com.esc.common.util.conditionbuilder.valuehandler; import java.sql.Timestamp; import java.util.GregorianCalendar; import java.util.List; import com.esc.common.exception.BusinessException; import com.esc.common.util.Condition; import com.esc.common.util.DateUtil; import com.esc.common.util.Operator; public class TimeStampValueHandler extends AbstractValueHandler { private static String CURRECT_DATE_FORMATE = " 正确的格式有:年-2009、 年月-200903、 年月日-20090328、年月日时分秒-20090328230159"; private static TimeStampValueHandler stringConditionBuilder = new TimeStampValueHandler(); private TimeStampValueHandler() { super(); } public static TimeStampValueHandler getInstance() { return stringConditionBuilder; } @SuppressWarnings("deprecation") @Override public void beforeDoAdd(List<Condition> conditios) { int conditionCount = conditios.size(); if (conditionCount == 2) {// 有两个条件 for (int i = 0; i < conditionCount; i++) { Condition condition = conditios.get(i); if (i == 0) {// 处理第一个条件 handleFirstCondition(condition); } else {// 处理第二个条件 handleSecondCondition(condition); } } } else if(conditionCount == 1){//只有一个条件,加一条件后递归 Condition condition = conditios.get(0); if(condition.getOperator().equals(Operator.EQ)){ //把条件变成大于等于 condition.setOperator(Operator.GE); //新增一个小于的条件 Condition condition2 = new Condition(condition.getProperty(),condition.getValue(),Operator.LT); conditios.add(condition2); beforeDoAdd(conditios); }else{ handleFirstCondition(condition); } } } private void handleFirstCondition(Condition condition){ Timestamp date = null; // 去除分隔符,前一个冒号是全角,后一个是半角 String value = cutChars(condition.getValue().toString()); int dateLength = value.length(); switch (dateLength) { case 14://精确到秒,直接取当秒的0毫秒0微秒 date = new Timestamp(DateUtil.convertStringToDate( "yyyyMMddHHmmss", value).getTime()); break; case 8://精确到天,取当天0时0分0秒 date = new Timestamp(DateUtil.convertStringToDate( "yyyyMMdd", value).getTime()); break; case 6://精确到月,取当前1号0时0分0秒 date = new Timestamp(new GregorianCalendar( getYearFromDateString(value), getMonthFromDateString(value) - 1, 1) .getTimeInMillis()); break; case 4://精确到年,取当年1月1号0时,0分0秒 date = new Timestamp(new GregorianCalendar( getYearFromDateString(value), 0, 1) .getTimeInMillis()); break; default: throw new BusinessException("您输入的时间:"+value+",格式不对"+CURRECT_DATE_FORMATE); } condition.setValue(date); } private void handleSecondCondition(Condition condition){ Timestamp date = null; // 去除分隔符,前一个冒号是全角,后一个是半角 String value = cutChars(condition.getValue().toString()); int dateLength = value.length(); switch (dateLength) { case 14://精确到秒,加999毫秒 date = new Timestamp(DateUtil.convertStringToDate( "yyyyMMddHHmmss", value).getTime()+999); break; case 8://精确到天,取下一天0时0分0秒再减一毫秒 date = new Timestamp(new GregorianCalendar(getYearFromDateString(value),getMonthFromDateString(value)-1,getDayFromDateString(value)+1).getTimeInMillis()-1); break; case 6://精确到月,取下一月1号0时0分0秒再减一毫秒 date = new Timestamp(new GregorianCalendar(getYearFromDateString(value),getMonthFromDateString(value),1).getTimeInMillis()-1); break; case 4://精确到年,取下一年1月1号0时0分0秒再减一毫秒 date = new Timestamp(new GregorianCalendar(getYearFromDateString(value)+1,0,1).getTimeInMillis()-1); break; default: throw new BusinessException("时间输入格式不对:"+value+CURRECT_DATE_FORMATE); } condition.setValue(date); } private String cutChars(String src) { return src.replaceAll(":", "").replaceAll("-", "").replaceAll(":", "") .replaceAll("/", "").replaceAll(" ", ""); } @Override public Class<Timestamp> getDealType() { return Timestamp.class; } }
其它类型的日期是委托此类完成的,如处理java.util.date类型条件的类代码
package com.esc.common.util.conditionbuilder.valuehandler; import java.util.Date; import java.util.List; import com.esc.common.util.Condition; @SuppressWarnings("unchecked") public class DateValueHandler extends AbstractValueHandler { private static DateValueHandler dateConditionBuilder = new DateValueHandler(); private DateValueHandler(){ super(); } public static DateValueHandler getInstance() { return dateConditionBuilder; } //使用TimeStampConditionDealer来处理 public void beforeDoAdd(List<Condition> conditios) { TimeStampValueHandler.getInstance().beforeDoAdd(conditios); } @SuppressWarnings("unchecked") @Override public Class getDealType() { return Date.class; } }
发表评论
-
一个很方便的Hibernate自动拼装条件工具类
2010-03-18 20:43 3510每做一个新的模块都要写一大堆组装查询条件的逻辑代码,不小心有一 ... -
hibernate的一个BUG
2010-03-02 20:03 1718BUG简单描述:在Criteria ... -
基于HIBERNATE的全自动查询框架(三)
2009-10-13 22:17 3176本篇讲解“标准条件处理器”,此处理器实现了ICondition ... -
基于HIBERNATE的全自动查询框架(二)
2009-09-30 16:48 4042欢迎加入阿里,有兴趣的发邮件给我fuqu.lgd@alibab ... -
如何干预HIBERNATE二级缓存
2009-09-24 21:04 2659此文的目的只是想把HIBERNATE缓存和应用的 ... -
基于HIBERNATE的全自动查询框架(一)
2009-09-23 18:48 2367本文讨论如何实现 ... -
使用HIBERNATE的SQL查询并将结果集自动转换成POJO
2009-09-21 11:08 42045在某些场合下,我们可能想使用HIBERNATE的框架提供的SQ ... -
使用HIBERNATE的DetachedCriteria无限级联取部份字段的查询结果集转换
2009-09-20 23:26 9282--后记,本文所讲的实 ...
相关推荐
在这个物流系统中,Hibernate用于将业务对象(如订单、货物、客户等)映射到数据库表,通过SQL查询操作数据,而无需直接编写大量的SQL语句,提高了开发效率和代码的可维护性。 2. **Spring**:Spring是Java企业级...
【标题】:基于Hibernate和SpringMVC框架的小型书店管理网站S 【描述】:小型书店管理网站是一个常见的Web应用程序示例,它利用了Hibernate和SpringMVC这两个强大的开源框架。Hibernate是Java领域中广泛使用的对象...
本教程将详细阐述如何利用MyEclipse10,一个强大的Java EE集成开发环境,搭建一个基于Struts2.1、Spring3.3和Hibernate3.3的全注解框架。这种框架被称为SSH2,因为它包含了Struts2、Spring和Hibernate这三大主流Java...
这个文档最全版可能涵盖了上述所有内容,以及更详细的使用示例和配置说明,帮助开发者深入理解和应用Hibernate 4.0.0 Beta5框架。通过阅读这份文档,你可以全面了解Hibernate的基础概念、配置、API使用以及最佳实践...
《基于Hibernate,Spring,Spring MVC,Bootstrap框架的管理系统详解》 在现代企业级应用开发中,选择合适的框架能够显著提高开发效率,降低维护成本。本文将深入探讨一个基于Hibernate、Spring、Spring MVC以及...
此外,它还可以生成基于Hibernate的DAO(数据访问对象)层,进一步提高了开发效率。 接下来是hibernate-annotations-3.3.0.GA,这是Hibernate 3.x系列的一个版本,包含了Hibernate的注解支持。在Java中,注解是一种...
**基于Struts+Hibernate的网上问卷调查系统** 在IT领域,构建一个网上问卷调查系统是一项常见的任务,它能够帮助企业、研究机构或者个人收集用户数据,进行统计分析。本项目采用Struts2作为前端MVC框架,Hibernate...
基于Spring+SpringMVC+Hibernate的全注解开发,允许开发者摆脱传统的XML配置文件,转而使用注解来实现组件的配置,大大简化了开发流程,提高了开发效率。 **Spring框架** 是一个全面的后端应用管理框架,它提供了...
Smart框架是一种基于SpringMVC、Spring和Hibernate的整合框架,旨在简化企业级Web应用的开发工作。这个框架利用了Maven进行项目管理和构建,确保了依赖管理的有效性和一致性。通过集成这些主流的技术栈,Smart提供了...
本项目是一个基于Spring、Spring MVC、Hibernate和Material前端框架构建的简单BBS论坛系统,旨在为初学者提供一个学习和实践这些技术的平台。在这个系统中,你可以看到如何将Java后端技术和现代化的前端设计结合,以...
总的来说,"jsp+Struts+hibernate基本框架搭建demo"是一个典型的Java Web应用开发实践,涵盖了前端展示、后端控制和数据库操作的全过程。通过这样的示例,开发者可以学习到如何在实际项目中有效地组织代码和配置,...
**基于全注解的SSH2框架详解** SSH2框架,即Spring、Struts2和Hibernate的集成,是Java开发Web应用程序的主流框架之一。在这个基于全注解的SSH2框架中,我们将深入探讨如何利用注解来简化配置,提高开发效率,并...
以下将详细阐述这三个框架的核心功能和它们在OA(办公自动化)项目中的应用。 **Struts2框架** Struts2是一个基于MVC(Model-View-Controller)设计模式的Web应用框架,它主要负责控制层。Struts2通过拦截器机制...
《Jeesite Web框架:Hibernate、Spring与Shiro深度整合》 Jeesite是一个开源的Java Web框架,它集成了Hibernate、Spring和Shiro等组件,构建了一个强大的企业级应用开发平台。这篇文档将深入探讨这三大技术在...
查询房源则可以使用`Query`或`Criteria` API,通过HQL(Hibernate Query Language)或SQL编写查询语句。 进一步地,租房系统可能需要处理复杂的业务逻辑,比如租赁合同的签订和管理。这可能涉及到多个实体间的关联...
- **自动化的持久化操作**:Hibernate能够自动生成大部分SQL语句,大大减轻了开发者的负担。 - **支持多种数据库**:Hibernate支持多种关系型数据库,包括MySQL、Oracle、SQL Server等,使得迁移变得容易。 - **强大...
【描述】"基于hibernate5 泛型Dao实例,下载后改一下数据库配置直接可以用",意味着这个压缩包文件提供了一个已经实现好的Hibernate5版本的泛型Dao示例项目。用户只需要根据自己的数据库环境修改相应的配置信息,就...
Spring框架则是一个全方位的应用框架,它不仅提供了依赖注入(DI)和面向切面编程(AOP)的功能,还集成了大量的其他框架,如数据访问、事务管理等。在人力资源管理系统中,Spring作为整体的容器,管理着所有bean的...