`

基于HIBERNATE的全自动查询框架(四)

阅读更多
这是全自动查框架最后一篇,主要讲解上一篇中最后提到的各种类型的值的处理器,这些处理器最终将:
    对字符串继使用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;
	}
}

  • 大小: 28.1 KB
1
0
分享到:
评论

相关推荐

    基于JavaEE的快速开发框架

    Hibernate是后来又补上的,最早的版本没有是因为第一个版本是为游戏服务器架构的,唯快不破的准则放弃了Hibernate,而后面增加回来是基于后台管理功能的需要。这一过程纠正了我一个开发框架中只能存在一个ORM的想法...

    基于 JavaEE 的快速开发框架 Tephra-JavaEE

    Tephra旨在构建一个稳定、高效、易于集群、快速扩展的JavaEE开发框架。目前,Tephra已经具备了以下特性: 提供类级别的热更新,但仅建议在需要快速修正严重BUG、并且无法立即进行全更新时使用。 提供全冗余方式的...

    BeetlSQL数据库访问框架是一个全功能 DAO 工具,同时具有 Hibernate.rar

    BeetSql是一个全功能DAO工具,同时具有Hibernate 优点 & Mybatis优点功能,适用于承认以SQL为中心,同时又需求工具能自动能生成大量常用的SQL的应用。 在开发效率上,无需注解,自动使用大量内置SQL,轻易完成增删...

    基于SSH框架的BBS论坛JavaEE项目源码

    10、最近登录过(三天,一周、一个月、三个月、半年)查询 11、类似微信团队号(与用户沟通账户以及推送系统消息) 12、QQ登录 jeebbsV4.0修复以及完善部分 1.权限的访问的地址链接 2.图片太大显示不全问题 3....

    Java的学习之路,学习JavaEE以及框架时候的一些项目,结合博客和源码,让你受益匪浅,适合Java初学者和刚入门开始学框架者

    [Spring]基于Spring框架的Web应用演示(附带cglib工具进行动态代理) [Tomcat7.0]Tomcat7版本安装包 [UltraISO]制作U盘启动盘需要的 [log4j_jar]log4j的支持包 [myAutoLoginWeb]过滤器Filter学习-实现用户的自动...

    基于JavaWEB+SSM+mysql框架构建的在线商城系统源码+数据库+项目说明(课程设计).zip

    本项目实现了通用 Mapper,免写 SQL,全自动处理关联查询。通过合理配置 MyBatis Generator 和自定义插件,灵活隔离手写代码和自动生成代码。实现了 BaseService 类对 Service 层进行抽象。通过拦截器实现了方法级...

    OA办公自动化管理系统(Struts1.2+Hibernate3.0+Spring2+DWR).rar

    SpringBoot 毕业设计,SpringBoot 课程设计,基于SpringBoot+Vue开发的,含有代码注释,新手也可看懂。ssm整合开发,小程序毕业设计、期末大作业、课程设计、高分必看,下载下来,简单部署,就可以使用。 包含:...

    SSM整合.zip

    mybatis它是轻量级持久层框架,由ibatis演化而来。它完成将数据库的结果集封装到对象中POJO。业务层控制层和使用Hibernate框架一样。Hibernate基于hql是完全...全自动ORM。Mybatis基于sql是半面向对象。半自动的ORM。

    TCCMS开源系统 v3.1

    内核借鉴了java中的struts和hibernate框架的一些思路,结合smarty MVC引擎自主研发的一套php ORM 框架。是一套高效,安全,开源的内容管理系统。 TCCMS 虽然功能不是最丰富的,可是是最实用的。最终目的是满足大...

    java web技术开发大全(最全最新)

    《Java Web开发技术大全:JSP+Servlet+Struts+Hibernate+Spring+Ajax》通过对SSH中的各种技术循序渐进地讲解,使读者尽快掌握开发基于SSH的Web程序的方法。《Java Web开发技术大全:JSP+Servlet+Struts+Hibernate+...

    mysql spring c3p0/dbcp/dbUtils工具支持包

    [Spring]基于Spring框架的Web应用演示(附带cglib工具进行动态代理) [Tomcat7.0]Tomcat7版本安装包 [UltraISO]制作U盘启动盘需要的 [log4j_jar]log4j的支持包 [myAutoLoginWeb]过滤器Filter学习-实现用户的自动登录与...

    基于SSH的自助纳税申报系统【项目源码+数据库脚本】(毕设)

    ​后台框架:Spring、Struts2、Hibernate ​数据库:MySQL 开发环境:JDK、Eclipse、Tomcat 三、系统功能 本自动纳税申报系统将功能模块分为管理员功能模块和用户功能模块两个模块,接下来对这两个模块进行展开论述...

    Spring面试题

    2. Hibernate是一个基于JDBC的主流持久化框架,是一个优秀的ORM实现。他很大程度的简化DAO层的编码工作 3. hibernate使用Java反射机制,而不是字节码增强程序来实现透明性。 4. hibernate的性能非常好,因为它是个...

    基于SSH的教材订购管理系统【项目源码+数据库脚本】(毕设)

    ​后台框架:Spring、Struts2、Hibernate ​数据库:MySQL 开发环境:JDK、Eclipse、Tomcat 三、系统功能 该系统的功能模块包括:教材征订模块、教材管理模块、教材领用模块、系统设置模块。 1.教材征订模块 教材...

    JSP基于SSH2网上书店购物网站-毕业设计-课程设计

    用了技术框架: HTML+CSS+JavaScript+jsp+mysql+Struts2+Spring+Hibernate --- 界面美观,功能齐全,适合用作毕业设计、课程设计作业等,项目均经过测试,可快速部署运行! 1、该资源内项目代码都经过测试运行成功...

    最新最全的spring开发包

     这个jar文件包含Web应用开发时,用到Spring框架时所需的核心类,包括自动载入WebApplicationContext特性的类、Struts与JSF集成类、文件上传的支持类、Filter类和大量工具辅助类。 (12) spring-webmvc.jar 这个...

    topJava:使用Java开发具有基于角色的授权和许可的功能齐全的Spring JPA Enterprise应用程序

    Java企业在线项目Java企业最需要的技术/工具/框架:Maven / Spring /安全性/ JPA(Hibernate)/ REST(杰克逊)/ Bootstrap(CSS)/ jQuery +插件。01.28:项目开始开始检查02.02交付HW0的截止日期04.02:第一堂课...

    Spring.3.x企业应用开发实战(完整版).part2

    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...

    Spring3.x企业应用开发实战(完整版) part1

    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...

Global site tag (gtag.js) - Google Analytics