`
墓里活人
  • 浏览: 22937 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论
  • 墓里活人: 回1楼: 具体的任务没有限定,根据你的需求来定。 比如我就 ...
    java线程池
  • ora92: 楼主,你的程序我试着运行了一下,能具体说一下它能完成什么任务吗 ...
    java线程池

HQL伪代码解析算法(易扩展)

阅读更多

解析的语法规则:

$req{key}$:
典型应用:
1.表示从 当前的requset中 获取数据 key为获取数据的键值.


$sen{key}$
典型应用:
1. $sen{User}$ 表示 从当前session中获取User对象的Id.
2. $sen{User.id}$ 与上面是等价的.
3. $sen{User.userName}$ 表示 从当前session中获取User对象的 用户名
4. $sen{User.field1.field2.fieild...n} 深层属性取值的时候.


$date{day,format}$
典型应用:
1. $date{3}$ 表示获取前三天的时间点 , 默认第二个参数可以不写 默认为:yyyy-MM-dd
2. $date{current}$ 获取当前时期 :默认格式为:yyyy-MM-dd


$time{hour,format}$
典型应用:
1. $time{8}$ 表示获取前8小时的时间点,第二个参数可以不写:默认格式为:yyyy-MM-dd HH:mm:ss
2. $time{current}$ 获取当前时间 :默认格式为:yyyy-MM-dd HH:mm:ss


以下为代码示例:

public class DynHqlUtil {
	
	
	/**
	 * hql语句装配 将伪代码转化为可执行代码
	 * 
	 * @param hql
	 * @return
	 * @throws Exception 
	 */
	public static String hqlLoader(String hql) throws Exception{
		
		DynHqlConfig cfg = new DynHqlConfig();
		DynHqlLoader loader = new DynHqlLoader();
		
		return loader.loader(hql, cfg);
	}
	
	
	public static void main(String[] args) {
		String hql;
		try {
			hql = DynHqlUtil.hqlLoader("from User where xxx = $date{7}$ and bb='k' and kk=$date{current}$");
			System.out.println( hql );
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		
	}

}


/***************************************************************************/

public class DynHqlConfig {
	
		  public static final char BOR = '$';  //$...$ 定义边框 
		  public static final char LEFTSIGN = '{';//  左 括 弧
		  public static final char RIGHTSIGN = '}';// 右 括 弧
		  
		  public static final String REQ = "req";//$req{key}$ 定义HttpRequest
		  public static final String SEN = "sen";//$sen{key}$ 定义HttpSession
		  public static final String DATE = "date";//$date{day,format}$ 定义日期
		  public static final String TIME = "time";//$time{hour}$ 定义时间
	
	      public static final String DATE_CURRENT ="current";//定义 本地当前时间
	      
	      private Map<String,String> mapKey;
	
	      public DynHqlConfig(){
	    	     
	    	     //此处重定义 伪代码key值
	    	     mapKey = new HashMap<String, String>();
	    	     
	    	     mapKey.put("user",Constants.USER_AUTH);//定义取用户的 key值
	      }
	      
		  public String getKey( String contentKey ) {
			  	 
			     String key = contentKey.trim().toLowerCase();
			     if( !mapKey.containsKey(key) )
			    	 return key;
			     
			     return mapKey.get(key);
		  }
}

/*******************************************************************************/

@SuppressWarnings("unused")
public class DynHqlLoader {
	
	static char[] hex = "0123456789ABCDEF".toCharArray();
	
	private StringBuilder buf ;
	private DynHqlConfig cfg ;
	
	private int  startInx = 0;
	private int  endInx   = -1;
	
	//边框 开始与结束
	private boolean borStar = false;
	private boolean borEnd = false;
	//大括弧 开始与结束 
	private boolean bracStar = false;
	private boolean bracEnd = false;
	
	/**
	 * 装配 hql 语句
	 * @param hql
	 * @param cfg
	 * @return
	 * @throws Exception 
	 */
	public String loader(String hql , DynHqlConfig cfg) throws Exception{
		
		this.cfg = cfg;
		this.buf = new StringBuilder();
		this.parseHql(hql);
		
		return buf.toString();
	}
	
	/**
	 * 解析 hql
	 * @param hql
	 * @throws Exception 
	 */
	@SuppressWarnings("static-access")
	private void parseHql(String hql) throws Exception{
		
		int length = hql.length();
		String str = "";
		CharacterIterator it = new StringCharacterIterator(hql);
        
		boolean sbor = false;
		boolean ebor = false;
		
		int inx = -1;
        for(char c = it.first(); c != CharacterIterator.DONE; c = it.next()) {
        	endInx++;//实时记录 当前处理的下标
        	
        	//当遇到第一个 $符号时 开始进入等待下一个对称$ 结束符的出现 否则视为语法错误 原样输出  
        	if( c == cfg.BOR ){ 
        		
        		if( sbor && !ebor  ) ebor =true; 
        		
        		if( !sbor ){
        			sbor = true;
        			this.appendHql(hql);
        		}
        	}
        	
        	
        	if(sbor && ebor){
        		sbor = ebor = false ;
        		this.appendFakcCode(hql);
        	}
        }
        
        String h = hql.substring(this.startInx,length);
	    this.buf.append(h);
	}
	
	/**
	 * 拼接 非动态部分 hql 
	 * 调整索引下标
	 * @param hql
	 */
	private void appendHql(String hql){
		
		String h = hql.substring(this.startInx,this.endInx);
		this.buf.append(h);
		
		this.startInx = this.endInx;
	}
	
	/**
	 * 处理 动态部分 hql 
	 * 调整索引下标
	 * @param hql
	 */
	@SuppressWarnings("static-access")
	private void appendFakcCode(String hql) throws Exception{
		
		String fcode = hql.substring(this.startInx,this.endInx+1);
		this.startInx = this.endInx+1;
		
		String value = fcode;
		
		System.out.println("之前:fcode  "+value);
		
		if( this.validBracket(fcode) ){
			
			if(fcode.indexOf(cfg.REQ )!=-1){
				value = this.request(fcode);
			}else if(fcode.indexOf(cfg.SEN )!=-1){
				value = this.session(fcode);
			}else if(fcode.indexOf(cfg.DATE )!=-1){
				value = this.date(fcode);
			} else if(fcode.indexOf(cfg.TIME)!=-1){
				value = this.time(fcode);
			}
		}
		
		System.out.println("之后:fcode  "+value);
		
		this.buf.append(value);
	}
	
	/**
	 * 从 HttpRequest 中取值
	 */
	@SuppressWarnings("static-access")
	private String request(String fcode){
		
		Object value = fcode;
		
		String[] params = null;
		String key = fcode.substring( fcode.indexOf(cfg.LEFTSIGN)+1,fcode.indexOf(cfg.RIGHTSIGN) );
		
		if(key!=null){
			params = (String[])ServletActionContext.getContext().getParameters().get(key.trim());
		    if( params!=null && params.length>=1 ){
		    	value = params[0];
		    }
		}
		
		return value.toString();
	}
	
	/**
	 * 从 HttpSession 中取值
	 */
	@SuppressWarnings("static-access")
	private String session(String fcode)throws Exception{
		
		String value = fcode;
		String content = fcode.substring( fcode.indexOf(cfg.LEFTSIGN)+1,fcode.indexOf(cfg.RIGHTSIGN) );
		
		Object obj = null;
		String key = null;
		
		if(content!=null){
			
			//假设 单对象的情况
			if( content.indexOf(".")==-1 ){
					key = cfg.getKey(content);
					if( key!=null )
					    obj = ServletActionContext.getContext().getSession().get( key );
					
					if( obj != null  && key != null ){
						
						String methodName = "getId";
						if( methodName!=null )
						value = (String)obj.getClass().getMethod( methodName ).invoke(obj);
				    }
			}
			//假设 对象.属性的情况
			if( content.indexOf(".")!=-1 ){
					String[] prop = content.split("\\.");
					
					key = cfg.getKey(prop[0]);
					if( key!=null )
					    obj = ServletActionContext.getContext().getSession().get( key );
					
					if( obj != null  && key != null ){
						//截取 属性链 (将属性链的第一个去掉)
						String nextPropLink = content.substring(content.indexOf(".")+1,content.length());
						value = this.getParameter(obj,nextPropLink);
					}
			}
		}
		
		return value ;
	}
	
	private String getParameter(Object obj , String propLink ) throws IntrospectionException, IllegalArgumentException, IllegalAccessException, InvocationTargetException{
		
		System.out.println( propLink );
		String[] fields = propLink.split("\\.");
		String fieldName = null;
		String nextPropLink = null;
		boolean exeRecursion = true; //是否继续执行递归
		
		if( fields.length == 1 ){
			exeRecursion = false;
			fieldName = fields[0];
		}
		
		if( fields.length > 1 ){
			exeRecursion = true;
			fieldName = propLink.substring(0,propLink.indexOf("."));
			nextPropLink = propLink.substring(propLink.indexOf(".")+1,propLink.length());
		}
		
		BeanInfo info = Introspector.getBeanInfo(obj.getClass());
		PropertyDescriptor[] props = info.getPropertyDescriptors();
		
		Object value = obj;
		
		for (int i = 0; i < props.length; i++) {
			
			 PropertyDescriptor prop = props[i];
			 String name = prop.getName();
			 
			 if( !name.equals( fieldName ) ){
				 continue;
			 }
			 Method method = prop.getReadMethod();
			 value = method.invoke(obj, new Object[0]);
			 
			 if(exeRecursion)
			    return this.getParameter(value, nextPropLink);
			 else
				break; 
		}
		
		return value.toString();
	}
	
	
	/**
	 * 获取相对 日期-时间
	 * 
	 * 解析格式 : $date{day,format}$ 第2个参数可不指定 默认为:默认时间格式:yyyy-MM-dd
	 * 默认格式 : $date{current}$ 默认时间格式:yyyy-MM-dd
	 * @param value
	 * @return
	 * @throws Exception 
	 */
	@SuppressWarnings("static-access")
	private String date(String fcode) throws Exception{
	    
		String content = fcode.substring( fcode.indexOf(cfg.LEFTSIGN)+1,fcode.indexOf(cfg.RIGHTSIGN) );
		String value = fcode ;
		if(content!=null){
			
				String[] args = content.split(",");
				
				if(args.length==2){
					
						//获取当前日期 $date{current,yyyy-MM-dd HH:mm:ss}$
						if( content.indexOf( cfg.DATE_CURRENT )!=-1 ){
							
							value =   this.date(0,args[1]);;
							
						} else {//获取指定的相对日期  $date{7,yyyy-MM-dd HH:mm:ss}$
							
							int day = -1;
							if( (day = this.validNumber(args[0]) )!=-1 ){
								value = this.date(day,args[1]);
							}
						}
				}
				
				if(args.length==1){
						
						//获取当前日期 $date{current}$
						if( content.indexOf( cfg.DATE_CURRENT )!=-1 ){
							
							value =  this.date(0,"yyyy-MM-dd");;
							
						} else {//获取指定的相对日期  $date{7}$
							
							int day = -1;
							if( (day = this.validNumber(args[0]) )!=-1 ){
								value = this.date(day,"yyyy-MM-dd");
							}
						}
				}
		}
		
		return value; 
	}
	
	/**
	 * 获取 指定的相对时间( 日期-时间 )
	 * 
	 * @param number
	 * @return
	 * @throws Exception
	 */
	private String date(int number,String format) throws Exception{
		
		long l = System.currentTimeMillis();
		long subDay = (24L*60L*60L*1000L)*(long)number;
		
		return DateUtil.getAppointTime( (l-subDay) ,format);
	}
	
	/**
	 *  获取相对 时间(小时)
	 *  
	 * 解析格式 : $time{hour,format}$ 第2个参数可不指定 默认为:默认时间格式:yyyy-MM-dd HH:mm:ss
	 * 默认格式 : $time{current}$ 默认时间格式:yyyy-MM-dd HH:mm:ss 
	 * @param fcode
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("static-access")
	private String time(String fcode)throws Exception{
		
		String content = fcode.substring( fcode.indexOf(cfg.LEFTSIGN)+1,fcode.indexOf(cfg.RIGHTSIGN) );
		String value = fcode ;
		if(content!=null){
			
				String[] args = content.split(",");
				
				if(args.length==2){
					
						//获取当前日期 $date{current,yyyy-MM-dd HH:mm:ss}$
						if( content.indexOf( cfg.DATE_CURRENT )!=-1 ){
							
							value =  this.time(0,args[1]);
							
						} else {//获取指定的相对日期  $date{7,yyyy-MM-dd HH:mm:ss}$
							
							int hour = -1;
							if( (hour = this.validNumber(args[0]) )!=-1 ){
								value = this.time(hour,args[1]);
							}
						}
				}
				
				if(args.length==1){
						
						//获取当前日期 $date{current}$
						if( content.indexOf( cfg.DATE_CURRENT )!=-1 ){
							
							value = this.time(0,"yyyy-MM-dd HH:mm:ss");
							
						} else {//获取指定的相对日期  $date{7}$
							
							int hour = -1;
							if( (hour = this.validNumber(args[0]) )!=-1 ){
								value = this.time(hour,"yyyy-MM-dd HH:mm:ss");
							}
						}
				}
		}
		
		return value; 
	}
	
	/**
	 * 获取 相对时间 (小时)
	 * @param hour
	 * @param format
	 * @return
	 * @throws Exception
	 */
	private String time(int hour,String format)throws Exception{
		
		long l = System.currentTimeMillis();
		long subHour = (60L*60L*1000L)*(long)hour;
		return DateUtil.getAppointTime(l-subHour,format);
	}
	
	/**
	 * 验证 括弧的合法性
	 * @return
	 */
	@SuppressWarnings("static-access")
	private boolean validBracket(String fakcCode){
		
		String fcode = fakcCode;
		boolean bool = false ;
		if( (fcode.indexOf(cfg.LEFTSIGN)!=-1) && (fcode.indexOf(cfg.RIGHTSIGN)!=-1)){
			bool = true ;
		}
		return bool;
	}
	
	/**
	 * 验证是否是 数字字符
	 * @param strNumber
	 * @return
	 */
	private int validNumber(String strNumber){
		
		String strNum = strNumber.trim();
		int ascall = -1;
		if(strNum!=null&&!"".equals(strNum)){
			for (int i = 0; i < strNum.length(); i++) {
				ascall = strNum.charAt(i);
				if(ascall<'0'|| ascall>'9') return -1;
			}
		}
		
		return Integer.parseInt( strNum );
	}  
}


分享到:
评论

相关推荐

    常用的hql语句用法解析

    本文将深入解析HQL语句的常见用法。 1. 大小写敏感性 HQL对Java类和属性的名称是大小写敏感的,但在关键字和表名方面,除了类名和属性名之外,HQL不区分大小写。因此,`SeLeCT`、`sELEct`和`SELECT`被视为相同,但`...

    hql.rar_HQL_Hibernate查询_登录的hql代码

    hibernate源码中的hql语句代码,添加,删除,修改,查询;hibernate源码中的hql语句代码,添加,删除,修改,查询

    全面解析HQL语句 非常详细直接的HQL语句的功能介绍

    标题:“全面解析HQL语句 非常详细直接的HQL语句的功能介绍” 描述:“非常详细直接实用的HQL语句的功能介绍看过的人保准都说好” 本篇文章将深入探讨HQL(Hibernate Query Language)的核心功能及其在数据查询...

    血缘关系解析工具源码_对hql集合进行静态分析_获取hql对应的血缘图.zip

    1. **语法解析**:源码首先需要对HQL语句进行语法解析,将查询语句拆分成可理解的组件,如表名、字段、函数和JOIN条件等。 2. **依赖关系识别**:通过对HQL的分析,识别出各个部分依赖的表、视图或函数,这些依赖...

    HQL语句 HQL语句

    HQL语句 HQL语句 HQL语句 HQL语句 HQL语句

    HQL Eclipse Plugins 配置教程

    不喜欢使用myEclipse的朋友可以尝试下 最近在项目中使用Hibernate,由于需要使用HQL,找了很多资料,大都是MyEclipse中自带的HQL工具。...工具很好用,可以识别出HQL文的语法正确,并且解析为标准SQL语句。

    解析HQL所需要的文件

    Hibernate在解析HQL生成SQL时需要的Java文件。压缩包里三个以.g为后缀的是规则文件,以.java为后缀的文件需要拷贝到Hibernate的源码org.hibernate.hql包下,便可运行

    最新HQL语句实例代码

    常见HQL语句的示例包括输出结果,以及语句的分析总结

    Hive 入门教程-Apache Hive入门介绍与HQL语法解析

    3. **获取 Hive 源码或可执行代码**:可以通过下载最新的发布包或从 Git 仓库克隆源代码。 4. **配置 Hive**:设置 Hive 如何连接到 Hadoop 和数据库。 5. **启动 Hive**:成功配置后,可以通过命令行界面启动 Hive...

    hql ppt Hql PPt

    Hql PPt Hql PPt

    sql解析,hql解析,hive脚本转mysql,解析hive,sparkSql,ER图自动生成、Excel自动生成.zip

    HQL是Hive的查询语言,它扩展了SQL,以适应大数据处理的需要。HQL解析同样包括词法和语法分析,但需处理如分区、桶、外部表等Hive特有的概念。解析HQL有助于在Hadoop集群上创建数据表、加载数据和执行复杂查询。 3....

    HQL语法入门学习HQL语法入门学习

    在Java开发中,Hibernate作为一个流行的ORM工具,通过HQL将对象模型与关系数据库之间的操作进行了抽象,使得开发者能够避免直接操作SQL,从而降低了数据库的耦合度,提高了代码的可读性和可维护性。HQL支持复杂的...

    HQL查询及语法

    以下是一些基础的HQL语法示例及其解析: 1. **基本查询** - `from Person as p`: 此语句用于从Person表中选择所有实例。这里的`as p`是可选的,用于指定结果集中的别名,便于后续引用。 2. **属性选择** - `...

    hql语句 使用大全

    ### HQL语句使用大全 HQL(Hibernate Query Language)是一种面向对象的查询语言,它提供了灵活而强大的数据检索方式,使开发人员能够更高效地与数据库交互。本文将详细介绍HQL的基本用法及高级特性。 #### 1. ...

    精通HQL(word格式)

    【HQL基础】 HQL,全称Hibernate Query Language,是Hibernate框架提供的面向对象的查询语言,它类似于SQL,但更专注于对象模型而非数据库表结构。...在实际开发中,掌握HQL的使用能极大地提升开发效率和代码质量。

    sql转换hql工具

    之前写好SQL,再到代码里面来写,语句复杂的看的时不时细节会忘记,用sql转换hql工具,直接贴近了就可以了;

    hql总条数.txt

    #### 代码解析 提供的代码段展示了如何使用HQL来获取数据库中特定表或查询结果的总条数。具体而言,`getRows`方法接受一个HQL查询字符串作为参数,并返回该查询结果的行数。 1. **参数解释**:`@param hql`注释...

Global site tag (gtag.js) - Google Analytics