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;   
	}   
 }  

 

你可能感兴趣的:(HQL生成器--查询语句)