解析的语法规则:
$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语句的常见用法。 1. 大小写敏感性 HQL对Java类和属性的名称是大小写敏感的,但在关键字和表名方面,除了类名和属性名之外,HQL不区分大小写。因此,`SeLeCT`、`sELEct`和`SELECT`被视为相同,但`...
hibernate源码中的hql语句代码,添加,删除,修改,查询;hibernate源码中的hql语句代码,添加,删除,修改,查询
标题:“全面解析HQL语句 非常详细直接的HQL语句的功能介绍” 描述:“非常详细直接实用的HQL语句的功能介绍看过的人保准都说好” 本篇文章将深入探讨HQL(Hibernate Query Language)的核心功能及其在数据查询...
1. **语法解析**:源码首先需要对HQL语句进行语法解析,将查询语句拆分成可理解的组件,如表名、字段、函数和JOIN条件等。 2. **依赖关系识别**:通过对HQL的分析,识别出各个部分依赖的表、视图或函数,这些依赖...
HQL语句 HQL语句 HQL语句 HQL语句 HQL语句
不喜欢使用myEclipse的朋友可以尝试下 最近在项目中使用Hibernate,由于需要使用HQL,找了很多资料,大都是MyEclipse中自带的HQL工具。...工具很好用,可以识别出HQL文的语法正确,并且解析为标准SQL语句。
Hibernate在解析HQL生成SQL时需要的Java文件。压缩包里三个以.g为后缀的是规则文件,以.java为后缀的文件需要拷贝到Hibernate的源码org.hibernate.hql包下,便可运行
常见HQL语句的示例包括输出结果,以及语句的分析总结
3. **获取 Hive 源码或可执行代码**:可以通过下载最新的发布包或从 Git 仓库克隆源代码。 4. **配置 Hive**:设置 Hive 如何连接到 Hadoop 和数据库。 5. **启动 Hive**:成功配置后,可以通过命令行界面启动 Hive...
Hql PPt Hql PPt
HQL是Hive的查询语言,它扩展了SQL,以适应大数据处理的需要。HQL解析同样包括词法和语法分析,但需处理如分区、桶、外部表等Hive特有的概念。解析HQL有助于在Hadoop集群上创建数据表、加载数据和执行复杂查询。 3....
在Java开发中,Hibernate作为一个流行的ORM工具,通过HQL将对象模型与关系数据库之间的操作进行了抽象,使得开发者能够避免直接操作SQL,从而降低了数据库的耦合度,提高了代码的可读性和可维护性。HQL支持复杂的...
以下是一些基础的HQL语法示例及其解析: 1. **基本查询** - `from Person as p`: 此语句用于从Person表中选择所有实例。这里的`as p`是可选的,用于指定结果集中的别名,便于后续引用。 2. **属性选择** - `...
### HQL语句使用大全 HQL(Hibernate Query Language)是一种面向对象的查询语言,它提供了灵活而强大的数据检索方式,使开发人员能够更高效地与数据库交互。本文将详细介绍HQL的基本用法及高级特性。 #### 1. ...
【HQL基础】 HQL,全称Hibernate Query Language,是Hibernate框架提供的面向对象的查询语言,它类似于SQL,但更专注于对象模型而非数据库表结构。...在实际开发中,掌握HQL的使用能极大地提升开发效率和代码质量。
之前写好SQL,再到代码里面来写,语句复杂的看的时不时细节会忘记,用sql转换hql工具,直接贴近了就可以了;
#### 代码解析 提供的代码段展示了如何使用HQL来获取数据库中特定表或查询结果的总条数。具体而言,`getRows`方法接受一个HQL查询字符串作为参数,并返回该查询结果的行数。 1. **参数解释**:`@param hql`注释...