论坛首页 Java企业应用论坛

面向组合子编程实验-SQL组合查询条件的简单实现

浏览 37522 次
该帖已经被评为精华帖
作者 正文
   发表时间:2006-08-10  
各位老大,有点跑题了,这个帖子是讨论组合子编程的技术,这只是我一个组合子实验性质的代码,谈不上具体的应用,说实话,我对组合子编程刚刚接触,一只半解,对于其适用的应用边界相当模糊,就是想通过讨论来进一步加深对组合子编程思想的理解,还是把视线集中到这来吧,比如,用组合子解决这类问题是否合适(先假设就有这需求),是否用错了地方,是否误用滥用组合子的地方,其他问题我们可以另外开贴讨论啊
0 请登录后投票
   发表时间:2006-08-10  
不错,这种业务相对稳定的情况非常适合使用组合子。

不过楼主少贴了com.zxchen.co.query.functors的代码。
0 请登录后投票
   发表时间:2006-08-11  
intolong 写道

不过楼主少贴了com.zxchen.co.query.functors的代码。

已经贴上来了,请重新下载附件。
0 请登录后投票
   发表时间:2006-08-11  
其实我在自己写一些简单的sql动态拼装的时候,也发现sql这个语言虽然直观,但是重用能力不好。

比如拼接了一段query q1,下面忽然需要对q1做一下top n操作,得,没辙,除非我parse这个q1字符串,否则top n就加不进去。

要是能做成这种组合子的形式就好了.




类似的需求很多,基本上要是join,in,projection, filter等等都能做成组合子形式就好了,比如:
Relation top(Relation rel, int n);;
Relation join(Relation r1, Relation r2, Predicate cond);;
Predicate in(Expression e, Relation rel);;
Relation project(Expression[] exprs, Relation rel);;
Relation where(Relation rel, Predicate filter);;
Predicate exists(Relation rel);;
Relation groupby(Relation rel, Predicate having);;
Relation orderby(Relation rel, Expression e);;
Relation alias(Relation rel, String alias);;
Relation apply(Relation rel, Map args);;



再加上在Predicate级别上的and, or, not,==,<>等等之类的简单组合子以及Expression级别上的组合子这就非常好了。

老兄的组合子仅仅还是在Predicate这个级别上搞,功能不太强大。

另外,组合规则太少。比如eq,只有“equalToExpr(String field,Object obj)”,而没有equalToExpr(Expression expr1,Expression expr2)

另外,一般来说Context, ParamsResult这些都属于实现细节,最好对客户隐藏。比如你的Mapper接口,最好就是Object map(Object),而不要对ParamsResult产生依赖。
0 请登录后投票
   发表时间:2006-08-11  
ajoo 写道
其实我在自己写一些简单的sql动态拼装的时候,也发现sql这个语言虽然直观,但是重用能力不好。

比如拼接了一段query q1,下面忽然需要对q1做一下top n操作,得,没辙,除非我parse这个q1字符串,否则top n就加不进去。

要是能做成这种组合子的形式就好了.




类似的需求很多,基本上要是join,in,projection, filter等等都能做成组合子形式就好了,比如:
Relation top(Relation rel, int n);;
Relation join(Relation r1, Relation r2, Predicate cond);;
Predicate in(Expression e, Relation rel);;
Relation project(Expression[] exprs, Relation rel);;
Relation where(Relation rel, Predicate filter);;
Predicate exists(Relation rel);;
Relation groupby(Relation rel, Predicate having);;
Relation orderby(Relation rel, Expression e);;
Relation alias(Relation rel, String alias);;
Relation apply(Relation rel, Map args);;



再加上在Predicate级别上的and, or, not,==,<>等等之类的简单组合子以及Expression级别上的组合子这就非常好了。

老兄的组合子仅仅还是在Predicate这个级别上搞,功能不太强大。

另外,组合规则太少。比如eq,只有“equalToExpr(String field,Object obj)”,而没有equalToExpr(Expression expr1,Expression expr2)

另外,一般来说Context, ParamsResult这些都属于实现细节,最好对客户隐藏。比如你的Mapper接口,最好就是Object map(Object),而不要对ParamsResult产生依赖。


偶像终于出现了 ,这个目前没什么太大的用途,只是一个实验性质的尝试,要真能搞出你说的这些功能当然好,不过我不知道组合子能不能对付这种情况,回头好好琢磨琢磨
0 请登录后投票
   发表时间:2006-08-11  
新开一帖
http://forum.iteye.com/viewtopic.php?p=131795

欢迎移步!
0 请登录后投票
   发表时间:2006-08-11  
yimlin 写道


老大是来踢场子的啊,呵呵,开个玩笑,别介意
0 请登录后投票
   发表时间:2006-08-11  
踢场子?还不敢啊。:D
看场的robin和版主们可是铁腕治版。

只是觉在expression路子上走下去,就趋向hibernate的路子上,不如换换DDD给的思路,看看是否是条明道!
0 请登录后投票
   发表时间:2006-08-12  
我也是一个还不太清晰的想法.

这种通过api组合query的方法,自然没有直接写sql直观。通过一些脚本的string interpolation功能,或者象ibatis的动态sql功能(其实ibatis的动态sql如果需求复杂起来,比如动态生成in(...)这种,也不是那么舒服的),得到的东西会更容易理解。


不过,直接拼接sql也不是一点问题没有,
1。重用能力还是不佳。给你任意一个sql字符串,跟你说我要额外再加一个filter条件,都很难做到。你不知道要用"and"还是"where",不知道要不要加括号。如果这个sql字符串已经有了order by,不管where还是and都工作不了。

2。直接写sql往往就绑定数据库。就说keyword,不同的数据库就不同。莫非你要每个表名字,列名字都用"[]"括起来?
还有,mssql有top n,有些别的数据库可能有别的语法,这都是问题呀。

3。sql本身有些时候比较繁琐。比如说,
select 
Mean1 = avg(...);,
Mean2 = avg(...);,
Diff = Mean2 - Mean1,
Sum = sum(...);,
accm = exp(sum(log(...);););
from ...
where ...
group by ...

这个sql就不合法。非要"Diff=avg(...)-avg(...)",重复Mean1和Mean2的代码。


这些,都有希望通过sql api来解决的。还有就是楼主说的动态拦截query的问题,也可以方便地通过这种组合子来解决。

我一直没有真正着手去做这个东西,主要也是自己没有强烈的需求(因为目前来说,数据库绑定不是问题,用脚本,比如我的jaskell的string interpolation功能就够用了)。


不过,我怀疑这个东西真做出来也说不准会有用处。


至于说在spec上做文章,我因为没有太多切身经历,也说不好。不过感觉是,组合子仍然能够起很大作用的。它和sql组合应该是在不同层次的抽象上做文章。也许某个比另一个更有意义,但是绝对不是互相排斥的。

hibernate的criteria api就仅仅是在"where"上做文章吧?功能还是和这种完整的relational组合子有数量级上的差别的。
0 请登录后投票
   发表时间:2006-08-12  
iBATIS, lightor的做法是,

POJO + SQL Template = SQL。
POJO can be Map, or Java bean.

比如,
select
Mean1 = {mean1},
Mean2 = {mean2},
Diff = {mean2} - {mean1},
Sum = sum(...),
accm = exp(sum(log(...)))
from ...
where ...
// BEGIN DYNAMIC: user
user = {user}
// END DYNAMIC: user
group by ...
0 请登录后投票
论坛首页 Java企业应用版

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