该帖已经被评为精华帖
|
|
---|---|
作者 | 正文 |
发表时间:2006-08-10
各位老大,有点跑题了,这个帖子是讨论组合子编程的技术,这只是我一个组合子实验性质的代码,谈不上具体的应用,说实话,我对组合子编程刚刚接触,一只半解,对于其适用的应用边界相当模糊,就是想通过讨论来进一步加深对组合子编程思想的理解,还是把视线集中到这来吧,比如,用组合子解决这类问题是否合适(先假设就有这需求),是否用错了地方,是否误用滥用组合子的地方,其他问题我们可以另外开贴讨论啊
|
|
返回顶楼 | |
发表时间:2006-08-10
不错,这种业务相对稳定的情况非常适合使用组合子。
不过楼主少贴了com.zxchen.co.query.functors的代码。 |
|
返回顶楼 | |
发表时间:2006-08-11
intolong 写道 不过楼主少贴了com.zxchen.co.query.functors的代码。 已经贴上来了,请重新下载附件。 |
|
返回顶楼 | |
发表时间: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产生依赖。 |
|
返回顶楼 | |
发表时间: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产生依赖。 偶像终于出现了 ,这个目前没什么太大的用途,只是一个实验性质的尝试,要真能搞出你说的这些功能当然好,不过我不知道组合子能不能对付这种情况,回头好好琢磨琢磨 |
|
返回顶楼 | |
发表时间:2006-08-11
|
|
返回顶楼 | |
发表时间:2006-08-11
|
|
返回顶楼 | |
发表时间:2006-08-11
踢场子?还不敢啊。:D
看场的robin和版主们可是铁腕治版。 只是觉在expression路子上走下去,就趋向hibernate的路子上,不如换换DDD给的思路,看看是否是条明道! |
|
返回顶楼 | |
发表时间: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组合子有数量级上的差别的。 |
|
返回顶楼 | |
发表时间: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 ... |
|
返回顶楼 | |