论坛首页 Java企业应用论坛

介绍DynamicQueryTool,一个用于解决“拼装动态查询”的小工具。

浏览 37428 次
该帖已经被评为良好帖
作者 正文
   发表时间:2007-03-12  
为什么不用Hibernate自己的条件对象呢
0 请登录后投票
   发表时间:2007-03-12  
XMLDB 写道
以前不知是哪位已经贡献了很完美的解决方法了就是:
SQL= where (:a is not null and :a=xxx ) and/or (:b is not null and :b=xxx) ...
Code = new Object[]{model.getA(),model.getB()...}


这个把复杂性都放在SQL里了,虽然不用额外的Java代码,但是增大了SQL的长度,而且条件多时,会更严重,似乎也对于SQL的调试不方便。
0 请登录后投票
   发表时间:2007-03-12  
这个小工具 我发布到 sourceforge上了。
cvs -d:pserver:anonymous@dynamicquery.cvs.sourceforge.net:/cvsroot/dynamicquery login

地址:
https://sourceforge.net/projects/dynamicquery/

大家感兴趣的话,可以下载源代码看看。里面有完整的测试样例。

如果大家觉得可以基于这个小工具来做二次开发,也欢迎下载。

0 请登录后投票
   发表时间:2007-03-12  
ajoo 写道

2。这个自定义断言难道不能在参数值上下功夫?毕竟sql最好保持sql,逻辑还是在java里为妙。比如:
String hql = "select o from User o where o.name = $name";
HashMap params = new HashMap();
params.put("name", notEmptyStr(name));
DynamicQResult dr = qt.generate(hql, params);


让notEmptyStr在string为空的时候返回null或者一个你们自己特定的Null Object可行么?


返回null对于SQL而言应该不合适。
1.增大了不必要的SQL解析和运算,以及使SQL不那么清晰。
2.Null或者类似对象在SQL中不能用=、like等常规操作符号比较,一般只有is null、is not null
0 请登录后投票
   发表时间:2007-03-12  
Lucas Lee 写道
ajoo 写道

2。这个自定义断言难道不能在参数值上下功夫?毕竟sql最好保持sql,逻辑还是在java里为妙。比如:
String hql = "select o from User o where o.name = $name";
HashMap params = new HashMap();
params.put("name", notEmptyStr(name));
DynamicQResult dr = qt.generate(hql, params);


让notEmptyStr在string为空的时候返回null或者一个你们自己特定的Null Object可行么?


返回null对于SQL而言应该不合适。
1.增大了不必要的SQL解析和运算,以及使SQL不那么清晰。
2.Null或者类似对象在SQL中不能用=、like等常规操作符号比较,一般只有is null、is not null

1。不认为这是不必要的。哪里不清晰了?
2。你似乎误会了。这个null是给qt.generate()这个函数用的。当它发现某个参数是null或者NullObject的时候,直接省略掉使用这个变量的sql子句。这样做的目的是可以支持这种动态sql,而同时又不必在sql中引入标签。
例子中的sql如果name为null,那么生成的最终sql会是:
"select o from User o",没有null什么事。

0 请登录后投票
   发表时间:2007-03-12  
ajoo 写道


两点想法:
1。自定义断言的需求是否频繁到值得去影响不需要预定义断言的那大部分用户的易用性?可不可以考虑只处理90%的一般情况?(就象rails干脆不支持复合key一样?)
2。这个自定义断言难道不能在参数值上下功夫?毕竟sql最好保持sql,逻辑还是在java里为妙。比如:
String hql = "select o from User o where o.name = $name";
HashMap params = new HashMap();
params.put("name", notEmptyStr(name));
DynamicQResult dr = qt.generate(hql, params);


让notEmptyStr在string为空的时候返回null或者一个你们自己特定的Null Object可行么?


这个和查询语句绑的太紧了,可能影响动态生成结果的不一定是查询语句上的值。
0 请登录后投票
   发表时间:2007-03-12  
ajoo 写道

1。不认为这是不必要的。哪里不清晰了?
2。你似乎误会了。这个null是给qt.generate()这个函数用的。当它发现某个参数是null或者NullObject的时候,直接省略掉使用这个变量的sql子句。这样做的目的是可以支持这种动态sql,而同时又不必在sql中引入标签。
例子中的sql如果name为null,那么生成的最终sql会是:
"select o from User o",没有null什么事。



是的,我误会了
0 请登录后投票
   发表时间:2007-03-12  
很多人对这个工具提出疑问,当时开发这个工具主要是基于以下这个需求:

完整的可以查看的查询语句 。
     这点,如果通过自己用if/else来组装的话,很难满足需求,最终导致查询语句被分割到代码不同部分。
hibernat提供的查询工具是通过接口的形式。虽然很灵活,但是在代码易读上带来一定的复杂度, 如果可以观看整体的查询语句,那更加好了。



为了满足的动态组装查询又可以易读 查询语句的需求,我们开发了这个小工具。
当初第一个确定的大体格式是这样子:
<count>select count(o)</count><list>select o </list>
From User u <city|depName>join u.dep dep</city|depName> where 1=1 <name>and u.name = ?</name><sex>and u.sex=?</sex><age>and u.age=?</age><depName>and dep.name=?</depName><city>and dep.city=?</city><count>group by u.name</count><list>order by u.age</list>




上面的语句就是作为一个查询的文本,可以放在任何方便管理的地方,比如DAO的static field,或者一个properties里面。

里面这些tag: count,list,city,depName,name,sex....
都是用户自己定义的标识。 用户在以后可以”赋予这些标识“以一个”是否有效的“的标识(true/false) ,
这些标签内的内容,默认是被"ignore"的(另外一种对应的模式是 ”accept"),如果什么都不作,那么直接生成的query语句就是“忽略”所有标签内的内容,结果就是:From User u  where 1=1

如果用户希望接受某个标签可以这样:
q.accept("count")  


如果用户希望在runtime时候做判断,那么可以这样
q.accept("name",vo.getName()!=null)


这里还值得一说的是: city|depName 。这里面用到了”表达式“的概念,他表示的意思是说:
如果city标签被接受或者depName标签被接受,那么这个标签里面的内容”join u.dep dep" 就被接受。


另外,我们也提供了自定义标签的扩展,如果不喜欢XML标签,而是喜欢"{}",那么可以自己声明这个标签的样式:
qt.setFilterTag("ignore","{"," "," ","}"));


然后查询语句就可以这样写:
{count select count(o) count} {list select o  list}
From User u {city|depName join u.dep dep city|depName} where 1=1 {name and u.name = ? name} ......



设置参数也是非常直白的,就是不用考虑哪些需要过滤,而是直接基于整体的语句来设置参数,比如上面的例子:
q.setParam(1,"userName").setParam(2,"femail").setParam(3,25).setParam(4,"HR").setParam(5,"BEIJING")



至于说到维护的问题,看到如此直白的语句,我相信维护还是变得更容易的。

至于说“调试”的问题,我想,还是需要充分的侧试来保证的。

另外,这个工具也就定位在这个非常小的需求上面,当然了,肯定“不合“很多人的胃口,”萝卜青菜“各有所好。  哈哈,不过,希望更多的人可以喜欢这个小工具,如果这个小工具能够为你的项目开发带来一定效率的提升,我们就更高兴了。同时也欢迎大家提出更多的意见, 我们会继续改进和完善的。

      
0 请登录后投票
   发表时间:2007-03-12  
firebody 写道
这个小工具 我发不到 sourceforge上了。
cvs -d:pserver:anonymous@dynamicquery.cvs.sourceforge.net:/cvsroot/dynamicquery login

地址:
https://sourceforge.net/projects/dynamicquery/

大家感兴趣的话,可以下载源代码看看。里面有完整的测试样例。

如果大家觉得可以基于这个小工具来做二次开发,也欢迎下载。



呵呵,发到,怎么写成发不到了。
0 请登录后投票
   发表时间:2007-03-12  
Lucas Lee 写道
XMLDB 写道
以前不知是哪位已经贡献了很完美的解决方法了就是:
SQL= where (:a is not null and :a=xxx ) and/or (:b is not null and :b=xxx) ...
Code = new Object[]{model.getA(),model.getB()...}


这个把复杂性都放在SQL里了,虽然不用额外的Java代码,但是增大了SQL的长度,而且条件多时,会更严重,似乎也对于SQL的调试不方便。

实际上在条件多时,这个方法的效能才体现出来,把SQL导致的复杂性封在SQL层,无论条件多少,这个语句的执行效果是完全可预计的可重复的,出了错,完全不必考虑是否是SQL语法拼错,也意味着调试的简单.
KISS, that's all.
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics