`

HQL生成器--查询语句

阅读更多
根据传入实体的属性值,生成HQL的查询语句,简化HQL的编写
利用java反射实现的简单的hql生成类
/**
 * commonUtilDC
 *com.neusoft.v4base.common
 *HqlModel.java
 */
package com.neusoft.cardafterservice.common.utils;

/**
 * @author wangxing
 * @since 2013-5-15
 *
 */
import java.beans.PropertyDescriptor;   
import java.lang.reflect.Field;   
import java.lang.reflect.Method;   
import java.util.List;
import java.util.Map;

/**  
  * 此类用来创建hql查询语句,能自动生成如下格式hql语句。<br>  
  * 使用getHql()方法来创建hql语句,此方法调用会抛出异常。<br>  
  * 此类需要你为其提供一个带有get和set方法的bean,类会根据其get的方法获得其值,如果get属性不为null则添加where条件。<br>  
  * 如果没有设置任何方法,则默认生成from BookInfo形式HQL语句。  
  *   
  * @version 1.0.0.0  
  * @author  
  *   
  */  
 public class HqlModel {   
   
     private Object object;   
     
     private Object objectJoin; 
     
     private Map map; 
   
     /**
	 * @return the map
	 */
	public Map getMap() {
		return map;
	}

	/**
	 * @param map the map to set
	 */
	public void setMap(Map map) {
		this.map = map;
	}

	/**
	 * @return the objectJoin
	 */
	public Object getObjectJoin() {
		return objectJoin;
	}

	/**
	 * @param objectJoin the objectJoin to set
	 */
	public void setObjectJoin(Object objectJoin) {
		this.objectJoin = objectJoin;
	}

	/**  
      * 是否开启模糊查询  
      */  
     private boolean likeSel;   
   
     public boolean isLikeSel() {   
        return likeSel;   
     }   
   
     /**  
      * 设置属性是否开启模糊查询  
      *   
      * @param likeSel  
      */  
     public void setLikeSel(boolean likeSel) {   
         this.likeSel = likeSel;   
     }   
   
     public Object getObject() {   
         return object;   
     }   
   
     public void setObject(Object object) {   
        this.object = object;   
     }   
   
     /**  
      * 允许不带参数实例化  
      */  
     private HqlModel() {   
     }   
   
     /**  
      * 使用指定的对象来获取一个HqlModel实例  
      *   
      * @param object  
      *            实例化时所需要的DTO对象  
     */  
     public static HqlModel newInstanceByObj(Object object,Object objectJoin,Map dateMap) {   
        HqlModel hqlModel = new HqlModel();   
         hqlModel.setObject(object); 
         hqlModel.setObjectJoin(objectJoin);
         hqlModel.setMap(dateMap);
        return hqlModel;   
    }   
     
     /**  
      * 用来进行创建hql语句的方法, 此方法可能抛出异常  
      *   
      * @return 根据传入对象的get方法构建的hql语句  
      */  
    public String getHql() throws Exception {   
    	Map map = getMap();
    	String beginDate = null;
    	String endDate = null;
    	if (this.getMap() != null) {
    		beginDate = CommonUtils.noe(map.get("beginDate"), "");
        	endDate = CommonUtils.noe(map.get("endDate"), "");
    	}  
        // 得到给定实例的类型。   
         Class<?> theClass = this.getObject().getClass();  
         String objectT = theClass.getSimpleName();
         
         //需要join的表
         Class<?> theClassJoin = null;
         String objectJoinT = null;
         if(this.getObjectJoin() != null){
        	 theClassJoin = this.getObjectJoin().getClass();  
        	 objectJoinT = theClassJoin.getSimpleName();
         }
        
         // 预准备好的hql语句。   
         StringBuffer sbf = new StringBuffer(); 
         
         if(this.getObjectJoin() != null){
        	 sbf.append("from "+objectT+" "+objectT.toLowerCase()+" join fetch "+objectT.toLowerCase()+"."+objectJoinT.toLowerCase()+"  where ");
         }else{
        	 sbf.append("from "+objectT+" "+objectT.toLowerCase()+"  where ");
         }
         
         // 获得该类所有属性。   
         Field[] fields = object.getClass().getDeclaredFields();   
         
         // 遍历所有属性   
         for (Field field : fields) { 
        	 String fieldName = null;
        	
        	 fieldName = field.getName();
        	 if(field.getType().toString().indexOf("com.") != -1){//说明是many-to-one的对象
        		 continue;  
        	 }
        	 String fieldNameForHql = objectT.toLowerCase()+"."+fieldName;
        	 
        	 //去掉entity自动生成的
        	 if (("id").equals(fieldName) ||("serialVersionUID").equals(fieldName) || ("pojoContext").equals(fieldName) ) {   
                 continue;   
             } 
        	 //去掉伪列,如日期段
        	 if (fieldName.indexOf("ForShow") != -1) {   
                 continue;   
             }   
        	 
//        	 if(fieldName.indexOf("ForQuery") != -1 && !"".equals(beginDate) &&!"".equals(endDate) ){//说明是需要按时间段查询的对象
//        		  sbf.append(fieldNameForHql + " >=str_to_date('"+beginDate+"','%Y-%m-%d')  and "+fieldNameForHql+"<=str_to_date('"+endDate+"','%Y-%m-%d')");
//                  sbf.append(" and ");   
//         	 }
        	 if(fieldName.indexOf("ForQuery") != -1 && !"".equals(beginDate)){
        	     sbf.append(fieldNameForHql + " >=str_to_date('"+beginDate+"','%Y-%m-%d')");
        	     sbf.append(" and ");  
        	 }
        	 if(fieldName.indexOf("ForQuery") != -1 && !"".equals(endDate)){
                 sbf.append(fieldNameForHql+"<=str_to_date('"+endDate+"','%Y-%m-%d')");
                 sbf.append(" and ");  
             }
             PropertyDescriptor pd = new PropertyDescriptor(fieldName,theClass);   
             // 获得所有属性的读取方法   
             Method getMethod = pd.getReadMethod();   
             // 执行读取方法,获得属性值   
             Object objTemp = getMethod.invoke(object);   
             // 如果属性值为null,就略过   
             if (objTemp == null) {   
                 continue;   
             }   
            
             // 如果不为空,则拼HQL
             if (isLikeSel()) {   // 判断是否开启模糊查询,添加查询条件,并且加上%%符号。   
                 sbf.append(fieldNameForHql + " like '%" + objTemp + "%'");   
                 sbf.append(" and ");   
              }//同理添加查询条件,不添加%%符号。   
             else {   
                  sbf.append(fieldNameForHql + "='" + objTemp + "'");   
                  sbf.append(" and ");   
             }   
         }   
         
         // 遍历join表的所有属性   
         if(this.getObjectJoin() != null){
        	 Field[] fieldsJoin = objectJoin.getClass().getDeclaredFields();   
	         for (Field field : fieldsJoin) { 
	        	 String fieldName = null;
	        	 fieldName = field.getName();
	        	 String fieldNameForHql = objectT.toLowerCase()+"."+objectJoinT.toLowerCase()+"."+fieldName;
	        	 
	        	 //去掉entity自动生成的
	        	 if (("id").equals(fieldName) ||("serialVersionUID").equals(fieldName) || ("pojoContext").equals(fieldName) ) {   
	                 continue;   
	             }   
	        	 
	        	 //去掉伪列,如日期段
	        	 if (fieldName.indexOf("ForShow") != -1) {   
	                 continue;   
	             }   
	        	 
	        	 if(fieldName.indexOf("ForQuery") != -1 && !"".equals(beginDate) &&!"".equals(endDate) ){//说明是需要按时间段查询的对象
	        		  sbf.append(fieldNameForHql + " >=str_to_date('"+beginDate+"','%Y-%m-%d')  and "+fieldNameForHql+"<=str_to_date('"+endDate+"','%Y-%m-%d')");
	                  sbf.append(" and ");   
	         	 }
	        	 
	             PropertyDescriptor pd = new PropertyDescriptor(fieldName,theClassJoin);   
	             // 获得所有属性的读取方法   
	             Method getMethod = pd.getReadMethod();   
	             // 执行读取方法,获得属性值   
	             Object objTemp = getMethod.invoke(objectJoin);   
	             // 如果属性值为null,就略过   
	             if (objTemp == null) {   
	                 continue;   
	             }   
	             
	             // 如果不为空。   
	            // 判断是否开启模糊查询,添加查询条件,并且加上%%符号。   
	             if (isLikeSel()) {   
	                 sbf.append(fieldNameForHql + " like '%" + objTemp + "%'");   
	                sbf.append(" and ");   
	             }//同理添加查询条件,不添加%%符号。   
	            else {   
	                 sbf.append(fieldNameForHql + "='" + objTemp + "'");   
	                 sbf.append(" and ");   
	            }   
	         }   
         }
         //最后一个属性设置完成之后取出残余的and和尾部的空格。   
        if (sbf.toString().endsWith("and ")) {   
             sbf.delete(sbf.length() - "and".length() - 1, sbf.length());   
        }   
         //如果没有设置任何属性,则取出尾部的where字符串和后面的空格。   
         if (sbf.toString().endsWith("where ")) {   
            sbf.delete(sbf.length() - "where".length() - 1, sbf.length());   
        }   
        //返回生成好的语句。   
       return sbf.toString();   
     }   
   
    /**
     * 多表查询时,使用此HQL生成器.
     * 注:适用的场景为一个主表中,包含多个fk(外键/many-to-one),即from AAA a join fetch a.BBB b join fetch a.CCC c;
     * 不支持from AAA a join fetch a.BBB b join fetch b.CCC c
     * @param objList
     * @return
     * @throws Exception String
     * @author wangxing
     * @since 2013-5-20
     */
    public String getHql(List<Object> objList) throws Exception {   
    	Map map = getMap();
    	String beginDate = null;
    	String endDate = null;
    	if (this.getMap() != null) {
    		beginDate = CommonUtils.noe(map.get("beginDate"), "");
        	endDate = CommonUtils.noe(map.get("endDate"), "");
    	}  
    	 // 预准备好的hql语句。   
        StringBuffer sbf = new StringBuffer(); 
        Object obj0 = objList.get(0);
        String objectT_0 = obj0.getClass().getSimpleName();
        sbf.append("from "+objectT_0+" "+objectT_0.toLowerCase());
        
        //多余2个Object时,增加join fetch
    	if(objList.size()>= 2){
    		for(Object obj_i:objList){
    			
    			//循环时,去掉第1个Object
    			if(obj_i.equals(obj0)){
    				 continue;  
    			}
        		Class<?> theClass = obj_i.getClass();  
        		String objectT_i = theClass.getSimpleName();
                sbf.append(" join fetch "+obj0.getClass().getSimpleName().toLowerCase()+"."+objectT_i.toLowerCase());
        	}
    	}
    	
    	 sbf.append(" where ");
         
         
         // 获得该类所有属性。   
         Field[] fields_0 = obj0.getClass().getDeclaredFields();   
         
         // 遍历所有属性   
         for (Field field_0 : fields_0) { 
        	 String fieldName = null;
        	
        	 fieldName = field_0.getName();
        	 if(field_0.getType().toString().indexOf("com.") != -1){//说明是many-to-one的对象
        		 continue;  
        	 }
        	 String fieldNameForHql = objectT_0.toLowerCase()+"."+fieldName;
        	 
        	 //去掉entity自动生成的
        	 if (("id").equals(fieldName) ||("serialVersionUID").equals(fieldName) || ("pojoContext").equals(fieldName) ) {   
                 continue;   
             } 
        	 //去掉伪列,如日期段
        	 if (fieldName.indexOf("ForShow") != -1) {   
                 continue;   
             }   
        	 
//        	 if(fieldName.indexOf("ForQuery") != -1 && !"".equals(beginDate) &&!"".equals(endDate) ){//说明是需要按时间段查询的对象
//        		  sbf.append(fieldNameForHql + " >=str_to_date('"+beginDate+"','%Y-%m-%d')  and "+fieldNameForHql+"<=str_to_date('"+endDate+"','%Y-%m-%d')");
//                  sbf.append(" and ");   
//         	 }
        	 if(fieldName.indexOf("ForQuery") != -1 && !"".equals(beginDate)){
        		 if(beginDate.length() > 13){
        			 sbf.append(fieldNameForHql + " >=str_to_date('"+beginDate+"','%Y-%m-%d %H:%i:%s')");
        		 }else{
        			 sbf.append(fieldNameForHql + " >=str_to_date('"+beginDate+"','%Y-%m-%d')");
        		 }
                 sbf.append(" and ");  
             }
             if(fieldName.indexOf("ForQuery") != -1 && !"".equals(endDate)){
            	 if(endDate.length() > 13){
        			 sbf.append(fieldNameForHql + " <=str_to_date('"+endDate+"','%Y-%m-%d %H:%i:%s')");
        		 }else{
        			 sbf.append(fieldNameForHql + " <=str_to_date('"+endDate+"','%Y-%m-%d')");
        		 }
                 sbf.append(" and ");  
             }
             PropertyDescriptor pd = new PropertyDescriptor(fieldName,obj0.getClass());   
             // 获得所有属性的读取方法   
             Method getMethod = pd.getReadMethod();   
             // 执行读取方法,获得属性值   
             Object objTemp = getMethod.invoke(obj0);   
             // 如果属性值为null,就略过   
             if (objTemp == null) {   
                 continue;   
             }   
            
             // 如果不为空,则拼HQL
             if (isLikeSel()) {   // 判断是否开启模糊查询,添加查询条件,并且加上%%符号。   
                 sbf.append(fieldNameForHql + " like '%" + objTemp + "%'");   
                 sbf.append(" and ");   
              }//同理添加查询条件,不添加%%符号。   
             else {   
                  sbf.append(fieldNameForHql + "='" + objTemp + "'");   
                  sbf.append(" and ");   
             }   
         }   
         
         if(objList.size()>= 2){
     		for(Object obj_i:objList){
     			//循环时,去掉第1个Object
    			if(obj_i.equals(obj0)){
    				 continue;  
    			}
    			
    			 Field[] fields_i = obj_i.getClass().getDeclaredFields();   
    			 for (Field field_i : fields_i) { 
    	        	 String fieldName = null;
    	        	 fieldName = field_i.getName();
    	        	 String objectT_i = obj_i.getClass().getSimpleName();
    	        	 String fieldNameForHql = objectT_0.toLowerCase()+"."+objectT_i.toLowerCase()+"."+fieldName;
    	        	 if(field_i.getType().toString().indexOf("com.") != -1){//说明是many-to-one的对象
    	        		 continue;  
    	        	 }
    	        	 
    	        	 if(field_i.getType().toString().indexOf("Set") != -1){//说明是many-to-one的对象
    	        		 continue;  
    	        	 }
    	        	 //去掉entity自动生成的
    	        	 if (("id").equals(fieldName) ||("serialVersionUID").equals(fieldName) || ("pojoContext").equals(fieldName) ) {   
    	                 continue;   
    	             }   
    	        	 
    	        	 //去掉伪列,如日期段
    	        	 if (fieldName.indexOf("ForShow") != -1) {   
    	                 continue;   
    	             }   
    	        	 
    	        	 if(fieldName.indexOf("ForQuery") != -1 && !"".equals(beginDate) &&!"".equals(endDate) ){//说明是需要按时间段查询的对象
    	        		  sbf.append(fieldNameForHql + " >=str_to_date('"+beginDate+"','%Y-%m-%d')  and "+fieldNameForHql+"<=str_to_date('"+endDate+"','%Y-%m-%d')");
    	                  sbf.append(" and ");   
    	         	 }
    	        	 
    	             PropertyDescriptor pd = new PropertyDescriptor(fieldName,obj_i.getClass());   
    	             // 获得所有属性的读取方法   
    	             Method getMethod = pd.getReadMethod();   
    	             // 执行读取方法,获得属性值   
    	             Object objTemp = getMethod.invoke(obj_i);   
    	             // 如果属性值为null,就略过   
    	             if (objTemp == null) {   
    	                 continue;   
    	             }   
    	             
    	             // 如果不为空。   
    	            // 判断是否开启模糊查询,添加查询条件,并且加上%%符号。   
    	             if (isLikeSel()) {   
    	                 sbf.append(fieldNameForHql + " like '%" + objTemp + "%'");   
    	                sbf.append(" and ");   
    	             }//同理添加查询条件,不添加%%符号。   
    	            else {   
    	                 sbf.append(fieldNameForHql + "='" + objTemp + "'");   
    	                 sbf.append(" and ");   
    	            }   
    	         } 
     		}
     		
         }
         
         //最后一个属性设置完成之后取出残余的and和尾部的空格。   
        if (sbf.toString().endsWith("and ")) {   
             sbf.delete(sbf.length() - "and".length() - 1, sbf.length());   
        }   
         //如果没有设置任何属性,则取出尾部的where字符串和后面的空格。   
         if (sbf.toString().endsWith("where ")) {   
            sbf.delete(sbf.length() - "where".length() - 1, sbf.length());   
        }   
        //返回生成好的语句。   
       return sbf.toString();   
     }

	/**
	 * @param dateMap
	 * @return HqlModel
	 * @author wangxing
	 * @since 2013-5-20
	 */
	public static HqlModel newInstanceByObj(Map dateMap) {
		 HqlModel hqlModel = new HqlModel();   
         hqlModel.setMap(dateMap);
        return hqlModel;   
	}   
 }  

 

0
0
分享到:
评论

相关推荐

    HQL连接查询和注解使用总结

    - 在HQL查询语句的`WHERE`子句中使用子查询。 - 关键字`ALL`, `ANY`/`SOME`, `IN`, `EXISTS`等可以用于子查询。 - **HQL提供的集合操作函数**: - `size()`/`size`: 获取集合中元素的数目。 - `minIndex()`/`...

    hql详细讲解,实例演示

    ]]&gt;`用于包裹HQL语句,防止特殊字符被解析。`&lt;filter-def&gt;`和`&lt;filter-param&gt;`定义了过滤器的参数,`myid`类型为整数。 在`Classes`类的映射中,`&lt;set&gt;`标签表示一个班级可以包含多个学生,`inverse="true"`表明...

    hibernate所用到HQL经典语句大全

    HQL(Hibernate Query Language)是一种面向对象的查询语言,它允许开发者使用类及其属性来编写查询语句,而不是传统的SQL语句。这使得开发人员可以更加专注于业务逻辑而非底层数据库的细节。 **1.1 基本查询** - *...

    hibernate课程详解

    - `Query`接口:执行HQL查询 #### 六、对象的三种状态 - **项目:上一个project** - 状态区分的关键点 - 三种状态: - 瞬时状态(Transient):对象未被持久化 - 持久化状态(Persistent):对象已被关联至...

    hql分页

    - **MyBatis**:在MyBatis中,可以通过`@SelectProvider`和自定义的SQL动态生成器来实现分页。 5. **源码分析** Hibernate的分页实现主要在`org.hibernate.query.Query`类中,`setFirstResult()`和`setMaxResults...

    NHibernate生成器

    【NHibernate生成器】是一种工具,专为使用Nhibernate框架的开发人员设计,能够自动化生成C#或VB.NET语言的数据持久化代码。Nhibernate是一个流行的开源对象关系映射(ORM)框架,它简化了在.NET环境中将数据库操作...

    SSH(示例及代码生成器)

    Hibernate支持实体类的自动持久化、事务管理和查询服务,提供HQL(Hibernate Query Language)和 Criteria 查询,使得数据操作更加便捷。 **Spring 2** 是一个全面的后端应用框架,它提供了依赖注入(DI)和面向切...

    弱智生成器

    "弱智生成器"可能是对一种代码生成工具的幽默称呼,这种工具能自动化生成Java实体类和对应的SQLMap文件,从而提高开发效率。 MyBatis是一个轻量级的框架,它的核心理念是将SQL语句与Java代码分离,通过XML或注解来...

    ssh代码自动生成器

    5. **持久层代码生成**:Hibernate的DAO接口和实现类,以及HQL或SQL查询语句会被自动生成,方便对数据库进行增删改查操作。 6. **视图层生成**:对于Struts2的项目,通常会生成JSP或Freemarker模板文件,这些文件...

    Nhibernet代码生成器

    **Nhibernate代码生成器**是一款用于提升开发效率的工具,它主要针对C#编程语言,基于Nhibernate框架设计。Nhibernate是一个流行的开源对象关系映射(ORM)框架,它允许开发者使用面向对象的方式操作数据库,而无需...

    hibernate 入门PPT

    - 属性映射:使用@Column、@Id等注解将类的属性映射到数据库的列,包括主键生成策略(如@Id生成器@GeneratedValue)。 4. **配置文件Hibernate.cfg.xml** - 数据源配置:如何配置连接到特定数据库的信息,如URL、...

    Hibernate在Myeclipse下SQL语句演示

    Myeclipse还提供了HQL编辑器和Criteria查询工具,支持代码提示、错误检查以及执行结果的可视化展示。 1. **配置Hibernate**: 在项目中引入Hibernate库,配置hibernate.cfg.xml,指定数据库连接等信息。 2. **创建...

    JEECG_v3开发指南v3.2.pdf

    - **查询条件SQL生成器**:介绍了如何使用JEECG的查询条件SQL生成器来生成复杂的查询语句。 - **实现原理**:详细解释了查询条件SQL生成器的工作原理。 - **查询规则**:提供了一些通用的查询规则,帮助开发者更...

    hibernate的映射表生成器

    Hibernate是Java领域中最受欢迎的ORM框架之一,它提供了强大的映射能力和查询语言HQL(Hibernate Query Language)。 2. **Hibernate配置**: 在使用Hibernate之前,开发者需要配置Hibernate的主配置文件(hibernate...

    antlr-2.7.5H3.jar和antlr-2.7.6rc1.jar

    ANTLR,全称是ANother Tool for Language Recognition,是一款强大的解析器生成器,广泛用于构建语言、工具和框架。在Java Persistence API(JPA)中,ANTLR扮演着关键的角色,特别是在处理对象关系映射(ORM)工具...

    尚硅谷 hive 课程教学文档

    - **解析器 (SQL Parser)**: 解析HQL语句。 - **编译器 (Physical Plan)**: 生成逻辑执行计划。 - **优化器 (Query Optimizer)**: 对执行计划进行优化。 - **执行器 (Executor)**: 将逻辑执行计划转换为可执行的...

    MyEclipse Hibernate 快速入门 中文版(PDF)

    **使用HQL编辑器**:利用MyEclipse提供的HQL编辑器编写和调试查询语句。 7. **测试应用**:创建一个简单的测试程序验证Hibernate配置是否正确。 #### 6. 测试Hibernate Demo应用 - **步骤**: 1. **编写测试...

    大数据技术之Hive-03(源码).pdf

    Hive是基于Hadoop的一个数据仓库工具,它可以将结构化的数据文件映射为一张数据库表,并提供简单的SQL查询功能,可以将SQL语句转换为MapReduce任务进行运行。本文将对Hive的核心组成、HQL语句如何转换为MR任务的源码...

Global site tag (gtag.js) - Google Analytics