`

基于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
分享到:
评论

相关推荐

    基于hibernate,spring,struts,shiro,activiti,easyui框架的物流系统,可做毕业设计

    在这个物流系统中,Hibernate用于将业务对象(如订单、货物、客户等)映射到数据库表,通过SQL查询操作数据,而无需直接编写大量的SQL语句,提高了开发效率和代码的可维护性。 2. **Spring**:Spring是Java企业级...

    基于Hibernate和SpringMVC框架的小型书店管理网站S

    【标题】:基于Hibernate和SpringMVC框架的小型书店管理网站S 【描述】:小型书店管理网站是一个常见的Web应用程序示例,它利用了Hibernate和SpringMVC这两个强大的开源框架。Hibernate是Java领域中广泛使用的对象...

    MyEclipse10+Struts2.1+Spring3.3+Hibernate3.3全注解框架搭建

    本教程将详细阐述如何利用MyEclipse10,一个强大的Java EE集成开发环境,搭建一个基于Struts2.1、Spring3.3和Hibernate3.3的全注解框架。这种框架被称为SSH2,因为它包含了Struts2、Spring和Hibernate这三大主流Java...

    hibernate的文档最全版

    这个文档最全版可能涵盖了上述所有内容,以及更详细的使用示例和配置说明,帮助开发者深入理解和应用Hibernate 4.0.0 Beta5框架。通过阅读这份文档,你可以全面了解Hibernate的基础概念、配置、API使用以及最佳实践...

    基于hibernate,spring,spring mvc,bootstrap框架开发的管理系统

    《基于Hibernate,Spring,Spring MVC,Bootstrap框架的管理系统详解》 在现代企业级应用开发中,选择合适的框架能够显著提高开发效率,降低维护成本。本文将深入探讨一个基于Hibernate、Spring、Spring MVC以及...

    hibernate相关插件全集

    此外,它还可以生成基于Hibernate的DAO(数据访问对象)层,进一步提高了开发效率。 接下来是hibernate-annotations-3.3.0.GA,这是Hibernate 3.x系列的一个版本,包含了Hibernate的注解支持。在Java中,注解是一种...

    基于Struts+Hibernate的网上问卷调查系统

    **基于Struts+Hibernate的网上问卷调查系统** 在IT领域,构建一个网上问卷调查系统是一项常见的任务,它能够帮助企业、研究机构或者个人收集用户数据,进行统计分析。本项目采用Struts2作为前端MVC框架,Hibernate...

    基于spring+springmvc+hibernate的全注解开发

    基于Spring+SpringMVC+Hibernate的全注解开发,允许开发者摆脱传统的XML配置文件,转而使用注解来实现组件的配置,大大简化了开发流程,提高了开发效率。 **Spring框架** 是一个全面的后端应用管理框架,它提供了...

    springmvc +spring+hibernate的smart框架

    Smart框架是一种基于SpringMVC、Spring和Hibernate的整合框架,旨在简化企业级Web应用的开发工作。这个框架利用了Maven进行项目管理和构建,确保了依赖管理的有效性和一致性。通过集成这些主流的技术栈,Smart提供了...

    spring、spring mvc、hibernate、material 前端框架开发简易BBS论坛系统

    本项目是一个基于Spring、Spring MVC、Hibernate和Material前端框架构建的简单BBS论坛系统,旨在为初学者提供一个学习和实践这些技术的平台。在这个系统中,你可以看到如何将Java后端技术和现代化的前端设计结合,以...

    jsp+Struts+hibernate基本框架搭建demo

    总的来说,"jsp+Struts+hibernate基本框架搭建demo"是一个典型的Java Web应用开发实践,涵盖了前端展示、后端控制和数据库操作的全过程。通过这样的示例,开发者可以学习到如何在实际项目中有效地组织代码和配置,...

    基于全注解的SSH2框架

    **基于全注解的SSH2框架详解** SSH2框架,即Spring、Struts2和Hibernate的集成,是Java开发Web应用程序的主流框架之一。在这个基于全注解的SSH2框架中,我们将深入探讨如何利用注解来简化配置,提高开发效率,并...

    OA项目struts2,spring,hibernate 三大框架

    以下将详细阐述这三个框架的核心功能和它们在OA(办公自动化)项目中的应用。 **Struts2框架** Struts2是一个基于MVC(Model-View-Controller)设计模式的Web应用框架,它主要负责控制层。Struts2通过拦截器机制...

    jeesite web框架hibernate+spring+shiro

    《Jeesite Web框架:Hibernate、Spring与Shiro深度整合》 Jeesite是一个开源的Java Web框架,它集成了Hibernate、Spring和Shiro等组件,构建了一个强大的企业级应用开发平台。这篇文档将深入探讨这三大技术在...

    使用Hibernate开发租房系统78.

    查询房源则可以使用`Query`或`Criteria` API,通过HQL(Hibernate Query Language)或SQL编写查询语句。 进一步地,租房系统可能需要处理复杂的业务逻辑,比如租赁合同的签订和管理。这可能涉及到多个实体间的关联...

    Struts、Spring、Hibernate三大框架的原理和优点

    - **自动化的持久化操作**:Hibernate能够自动生成大部分SQL语句,大大减轻了开发者的负担。 - **支持多种数据库**:Hibernate支持多种关系型数据库,包括MySQL、Oracle、SQL Server等,使得迁移变得容易。 - **强大...

    Hibernate泛型Dao

    【描述】"基于hibernate5 泛型Dao实例,下载后改一下数据库配置直接可以用",意味着这个压缩包文件提供了一个已经实现好的Hibernate5版本的泛型Dao示例项目。用户只需要根据自己的数据库环境修改相应的配置信息,就...

    Struts-Spring-Hibernate三大框架整合项目——人力资源管理系统

    Spring框架则是一个全方位的应用框架,它不仅提供了依赖注入(DI)和面向切面编程(AOP)的功能,还集成了大量的其他框架,如数据访问、事务管理等。在人力资源管理系统中,Spring作为整体的容器,管理着所有bean的...

Global site tag (gtag.js) - Google Analytics