日期:2014-05-16  浏览次数:20519 次

参考MongoDB输入格式的SQL生成器 by PHP

(需要php 5.3.x)这几天参考MongoDB的传入参数格式 find({a:1,$or:{c:1,b:2}}) 这样的表示方法,写了个由这种传入方法对数据进行解析 并输出带分析数据的array,以便后续class使用 不知道这种设计方法是否实用,里面的注释有可能写的不对,毕竟自己复制粘贴自己的也很多 源代码参见附件,这里贴出测试数据的结果以便表明我要做什么,欢迎交流指点 (贴个代码咋就这么难)

Array
(
    [parameters] => Array
        (
            [p11] => 1
            [p12] => foo
            [p13] => 1
            [p14] => 3
        )

    [into] => t1
    [write] => (`a`=:p11,`c`=:p12)
    [detail] => Array
        (
            [where] => Array
                (
                    [c] => 1
                    [a] => 1
                )

        )

    [query] =>  `c` = :p13  and `a` = :p14 
    [sql] => UPDATE `t1`  `c` = :p13  and `a` = :p14  SET (`a`=:p11,`c`=:p12) WHERE  `c` = :p13  and `a` = :p14 
)
1 楼 xieye 2011-06-21  
zend框架的select类可以组合sql
2 楼 achun 2011-06-21  
xieye 写道
zend框架的select类可以组合sql

我也尝试去看了多种框架的数据库查询支持情况,只要是用ActiveRecord的都对复杂查询支持的不好(也许我没有找到方法),我这个方案是通过传入参数的结构(参照Mongodb)来生成复杂查询的SQL语句的,比如
WHERE  ( ( `a` > :p1  and `c` in (:p2,:p3)) or ( ( ( `s` = :p4 ) or ( `a` = :p5 )) and (`cca` % ?   in (:p6,:p7,:p8))))

这种复杂条件ActiveRecord如何才能实现呢?
3 楼 yeaha 2011-06-21  
我猜测你的设计目的是提供一个通用的语法结构,成为sql的超集,兼容不同的sql标准。
程序里面使用通用的语法结构,以后即使切换数据库,也可以转换成为sql本地语言,不需要改程序。

但是这样设计的问题在于:
1、各种不同的sql特性其实是非常繁杂的,维护通用性其实会非常的困难。而且对这个超集的抽象和归纳基本上不太可能,到最后总会发现某些特例会超出原先的设计范畴。
2、使用了这种通用语法结构之后,丧失了灵活性,实际使用时,一些比较复杂的查询可能要绕不少弯子才能达到目的
3、读代码之前非得先熟悉这个语法结构才行,提高了维护和理解门槛

我认为提供一个通用的数据库中间层,以后即使切换到其它数据库,改改配置就好这件事情基本上属于神话,除非你的应用特别简单,否则都不太可能。

所以努力的方向不应该是不改程序,而是如何少改程序,不改是不可能的。

一个解决方案就是DataMapper,把逻辑跟存储隔离开。Adapter层面的差异是天然的,不应该抹掉,抹掉了反而不灵活,不自然。这种差异应该延迟到DataMapper的Mapper这个层面来解决。面向对象,抽象和封装就是用来解决这种问题的。
4 楼 achun 2011-06-21  
yeaha 写道
我猜测你的设计目的是提供一个通用的语法结构,成为sql的超集,兼容不同的sql标准。
程序里面使用通用的语法结构,以后即使切换数据库,也可以转换成为sql本地语言,不需要改程序。

但是这样设计的问题在于:
.....

是的,你猜的很对,不过我没有那么大的目标,只要支持几种常用的数据库就达到我的目标了
比如MySQL,SQLite,
而且在设计里面我采用的是独立class,也就是说每个都是独立设计的,根本不搞继承,以达到接口的特异性支持,你的回答让我确认了,目前还没有这样的成品,我就是怕已经有了成熟的东西,我还再这里重复造轮子。
DataMapper的问题主要是和业务逻辑结合太紧密,说白了就是每一个业务逻辑都是特例代码,这和手工代码已经区别不大了,这个应该在极其特殊的业务逻辑里面使用,而不能解决统一接口问题
感谢您的回复,我继续按这个思路进行,不求大而全。能支持大部分就好,20,80法则,特殊的还是要特别的设定sql,这个目前是没有好的解决方法的。
5 楼 yeaha 2011-06-21  
> DataMapper的问题主要是和业务逻辑结合太紧密,说白了就是每一个业务逻辑都是特例代码
没那么累,我给你看看我的DataMapper实现

https://github.com/yeaha/lysine/blob/master/framework/orm/datamapper.php
https://github.com/yeaha/lysine/tree/master/framework/orm/datamapper

实际使用例子
https://github.com/yeaha/lysine/blob/master/demos/rbac/model/user.php

每个Data可以定义自己的Mapper,也可以使用现成的Mapper,不一定非要每个Data对应一个Mapper
6 楼 achun 2011-06-21  
yeaha 写道
> DataMapper的问题主要是和业务逻辑结合太紧密,说白了就是每一个业务逻辑都是特例代码
没那么累,我给你看看我的DataMapper实现

https://github.com/yeaha/lysine/blob/master/framework/orm/datamapper.php
https://github.com/yeaha/lysine/tree/master/framework/orm/datamapper

实际使用例子
https://github.com/yeaha/lysine/blob/master/demos/rbac/model/user.php