`

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

相关推荐

    jdbc基础和参考

    查询对象,HQL Criteria 1.hibernate提供的更面向对象的一种查询方式。 准备工作: 1.java中的POJO对象存在 2.数据库,表得存在 3.hibernate的配置文件(hibernate.cfg.xml)得存在 4.POJO.hbm.xml文件存在 5....

    精通 Hibernate:Java 对象持久化技术详解(第2版).part2

     17.1.12 在HQL查询语句中绑定参数  17.1.13 设置查询附属事项  17.1.14 在映射文件中定义命名查询语句  17.1.15 在HQL查询语句中调用函数  17.2 设定查询条件  17.2.1 比较运算  17.2.2 范围运算  17.2.3 ...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part4

     17.1.12 在HQL查询语句中绑定参数  17.1.13 设置查询附属事项  17.1.14 在映射文件中定义命名查询语句  17.1.15 在HQL查询语句中调用函数  17.2 设定查询条件  17.2.1 比较运算  17.2.2 范围运算  17.2.3 ...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part3

     17.1.12 在HQL查询语句中绑定参数  17.1.13 设置查询附属事项  17.1.14 在映射文件中定义命名查询语句  17.1.15 在HQL查询语句中调用函数  17.2 设定查询条件  17.2.1 比较运算  17.2.2 范围运算  17.2.3 ...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part1.rar

     17.1.12 在HQL查询语句中绑定参数  17.1.13 设置查询附属事项  17.1.14 在映射文件中定义命名查询语句  17.1.15 在HQL查询语句中调用函数  17.2 设定查询条件  17.2.1 比较运算  17.2.2 范围运算  17.2.3 ...

    支持多数据库的ORM框架ef-orm.zip

    最大限度利用编译器减少编码错误的可能性 API设计和元数据模型(meta-model)的使用,使得常规的数据库查询都可以直接通过Criteria API来完成,无需使用任何JPQL/HQL/SQL。可以让避免用户犯一些语法、拼写等错误。...

    Hive用户指南(Hive_user_guide)_中文版.pdf

    3、 解释器、编译器、优化器完成 HQL 查询语句从词法分析、语法分析、编译、优化以及 查询计划的生成。生成的查询计划存储在 HDFS 中,并在随后有 MapReduce 调用执行。 4、 Hive 的数据存储在 HDFS 中,大部分的...

    Devart Entity Developer v6.4.719 Professional破解版,支持vs2019

    设计时LINQ / ESQL / HQL查询执行 查看和编辑源表中的数据 背景模型验证 基于T4模板的代码生成 大量预定义模板 生成C#或VB代码 每个类的文件,部分类生成 自定义属性支持 自定义模板支持 带语法高亮的模板编辑器 高...

    hibernate 框架详解

    触发器实现的主键生成器(Primary keys assigned by triggers) 6.1.5. composite-id 6.1.6. 鉴别器(discriminator) 6.1.7. 版本(version)(可选) 6.1.8. timestamp (optional) 6.1.9. property 6.1.10. ...

    specification-pattern-example:一个如何在Java中实现规范模式的示例

    可以选择实现知道如何将每个规范及其组合转换为SQL / HQL查询的转换器(请参阅Spring的ConversionService)。 举个例子 让我们想象一个幼儿园管理系统。 我们有孩子,他们有名字,年龄和喜欢玩具。 玩具有其颜色,

    hibernate3.04中文文档.chm

    触发器实现的主键生成器(Primary keys assigned by triggers) 6.1.5. composite-id 6.1.6. 鉴别器(discriminator) 6.1.7. 版本(version)(可选) 6.1.8. timestamp (optional) 6.1.9. property 6.1.10. ...

    Hibernate教程

    触发器实现的主键生成器(Primary keys assigned by triggers) 6.1.5. composite-id 6.1.6. 鉴别器(discriminator) 6.1.7. 版本(version)(可选) 6.1.8. timestamp (optional) 6.1.9. property 6.1.10. 多...

    最全Hibernate 参考文档

    触发器实现的主键生成器(Primary keys assigned by triggers) 5.1.5. composite-id 5.1.6. 鉴别器(discriminator) 5.1.7. 版本(version)(可选) 5.1.8. timestamp (optional) 5.1.9. property 5.1.10. 多对一...

    Hibernate3+中文参考文档

    触发器实现的主键生成器(Primary keys assigned by triggers) 5.1.5. composite-id 5.1.6. 鉴别器(discriminator) 5.1.7. 版本(version)(可选) 5.1.8. timestamp (optional) 5.1.9. property 5.1.10. 多对一...

    JAVA程序开发大全---上半部分

    9.3.2 使用HQL编辑器 154 9.4 Hibernate应用实例:基于Struts+Hibernate的登录系统 155 9.5 本章小结 160 第10章 Spring框架的开发及应用 161 10.1 Spring框架概述 161 10.2 Spring框架中的IoC编程 162 10.2.1 控制...

    Hibernate实战(第2版 中文高清版)

     12.2.1 使用HQL和JPA QL的大批量语句   12.2.2 利用批量处理   12.2.3 使用无状态的会话   12.3 数据过滤和拦截   12.3.1 动态数据过滤   12.3.2 拦截Hibernate事件   12.3.3 内核事件系统   12.3.4...

    Java学习笔记-个人整理的

    {12.13}DML语句}{175}{section.12.13} {12.13.1}insert}{175}{subsection.12.13.1} {12.13.2}create}{175}{subsection.12.13.2} {12.13.3}rownum}{175}{subsection.12.13.3} {12.13.4}update}{176}{subsection....

Global site tag (gtag.js) - Google Analytics