- 浏览: 117063 次
- 性别:
- 来自: 深圳
文章分类
最新评论
-
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 3456每做一个新的模块都要写一大堆组装查询条件的逻辑代码,不小心有一 ... -
hibernate的一个BUG
2010-03-02 20:03 1673BUG简单描述:在Criteria ... -
基于HIBERNATE的全自动查询框架(三)
2009-10-13 22:17 3097本篇讲解“标准条件处理器”,此处理器实现了ICondition ... -
基于HIBERNATE的全自动查询框架(二)
2009-09-30 16:48 3969欢迎加入阿里,有兴趣的发邮件给我fuqu.lgd@alibab ... -
如何干预HIBERNATE二级缓存
2009-09-24 21:04 2616此文的目的只是想把HIBERNATE缓存和应用的 ... -
基于HIBERNATE的全自动查询框架(一)
2009-09-23 18:48 2319本文讨论如何实现 ... -
使用HIBERNATE的SQL查询并将结果集自动转换成POJO
2009-09-21 11:08 42001在某些场合下,我们可能想使用HIBERNATE的框架提供的SQ ... -
使用HIBERNATE的DetachedCriteria无限级联取部份字段的查询结果集转换
2009-09-20 23:26 9206--后记,本文所讲的实 ...
相关推荐
Hibernate是后来又补上的,最早的版本没有是因为第一个版本是为游戏服务器架构的,唯快不破的准则放弃了Hibernate,而后面增加回来是基于后台管理功能的需要。这一过程纠正了我一个开发框架中只能存在一个ORM的想法...
Tephra旨在构建一个稳定、高效、易于集群、快速扩展的JavaEE开发框架。目前,Tephra已经具备了以下特性: 提供类级别的热更新,但仅建议在需要快速修正严重BUG、并且无法立即进行全更新时使用。 提供全冗余方式的...
BeetSql是一个全功能DAO工具,同时具有Hibernate 优点 & Mybatis优点功能,适用于承认以SQL为中心,同时又需求工具能自动能生成大量常用的SQL的应用。 在开发效率上,无需注解,自动使用大量内置SQL,轻易完成增删...
10、最近登录过(三天,一周、一个月、三个月、半年)查询 11、类似微信团队号(与用户沟通账户以及推送系统消息) 12、QQ登录 jeebbsV4.0修复以及完善部分 1.权限的访问的地址链接 2.图片太大显示不全问题 3....
[Spring]基于Spring框架的Web应用演示(附带cglib工具进行动态代理) [Tomcat7.0]Tomcat7版本安装包 [UltraISO]制作U盘启动盘需要的 [log4j_jar]log4j的支持包 [myAutoLoginWeb]过滤器Filter学习-实现用户的自动...
本项目实现了通用 Mapper,免写 SQL,全自动处理关联查询。通过合理配置 MyBatis Generator 和自定义插件,灵活隔离手写代码和自动生成代码。实现了 BaseService 类对 Service 层进行抽象。通过拦截器实现了方法级...
SpringBoot 毕业设计,SpringBoot 课程设计,基于SpringBoot+Vue开发的,含有代码注释,新手也可看懂。ssm整合开发,小程序毕业设计、期末大作业、课程设计、高分必看,下载下来,简单部署,就可以使用。 包含:...
mybatis它是轻量级持久层框架,由ibatis演化而来。它完成将数据库的结果集封装到对象中POJO。业务层控制层和使用Hibernate框架一样。Hibernate基于hql是完全...全自动ORM。Mybatis基于sql是半面向对象。半自动的ORM。
内核借鉴了java中的struts和hibernate框架的一些思路,结合smarty MVC引擎自主研发的一套php ORM 框架。是一套高效,安全,开源的内容管理系统。 TCCMS 虽然功能不是最丰富的,可是是最实用的。最终目的是满足大...
《Java Web开发技术大全:JSP+Servlet+Struts+Hibernate+Spring+Ajax》通过对SSH中的各种技术循序渐进地讲解,使读者尽快掌握开发基于SSH的Web程序的方法。《Java Web开发技术大全:JSP+Servlet+Struts+Hibernate+...
[Spring]基于Spring框架的Web应用演示(附带cglib工具进行动态代理) [Tomcat7.0]Tomcat7版本安装包 [UltraISO]制作U盘启动盘需要的 [log4j_jar]log4j的支持包 [myAutoLoginWeb]过滤器Filter学习-实现用户的自动登录与...
后台框架:Spring、Struts2、Hibernate 数据库:MySQL 开发环境:JDK、Eclipse、Tomcat 三、系统功能 本自动纳税申报系统将功能模块分为管理员功能模块和用户功能模块两个模块,接下来对这两个模块进行展开论述...
2. Hibernate是一个基于JDBC的主流持久化框架,是一个优秀的ORM实现。他很大程度的简化DAO层的编码工作 3. hibernate使用Java反射机制,而不是字节码增强程序来实现透明性。 4. hibernate的性能非常好,因为它是个...
后台框架:Spring、Struts2、Hibernate 数据库:MySQL 开发环境:JDK、Eclipse、Tomcat 三、系统功能 该系统的功能模块包括:教材征订模块、教材管理模块、教材领用模块、系统设置模块。 1.教材征订模块 教材...
用了技术框架: HTML+CSS+JavaScript+jsp+mysql+Struts2+Spring+Hibernate --- 界面美观,功能齐全,适合用作毕业设计、课程设计作业等,项目均经过测试,可快速部署运行! 1、该资源内项目代码都经过测试运行成功...
这个jar文件包含Web应用开发时,用到Spring框架时所需的核心类,包括自动载入WebApplicationContext特性的类、Struts与JSF集成类、文件上传的支持类、Filter类和大量工具辅助类。 (12) spring-webmvc.jar 这个...
Java企业在线项目Java企业最需要的技术/工具/框架:Maven / Spring /安全性/ JPA(Hibernate)/ REST(杰克逊)/ Bootstrap(CSS)/ jQuery +插件。01.28:项目开始开始检查02.02交付HW0的截止日期04.02:第一堂课...
10.5.2 Hibernate+Spring JDBC混合框架的事务管理 10.6 特殊方法成漏网之鱼 10.6.1 哪些方法不能实施Spring AOP事务 10.6.2 事务增强遗漏实例 10.7 数据连接泄漏 10.7.1 底层连接资源的访问问题 10.7.2 Spring JDBC...
10.5.2 Hibernate+Spring JDBC混合框架的事务管理 10.6 特殊方法成漏网之鱼 10.6.1 哪些方法不能实施Spring AOP事务 10.6.2 事务增强遗漏实例 10.7 数据连接泄漏 10.7.1 底层连接资源的访问问题 10.7.2 Spring JDBC...