Zend\Db TableGateway操作

Zend\Db TableGateway操作个人觉得设计不够友好。在内部如果需要构建复杂查询,还是直接SQL来得实在。但是对于简单的CURL,它就非常的擅长。Zend\Db 表的封装比1.x时代还少,大部分同学真正要的是简便的CURD操作,复杂的SQL,还是需要自己组装。不过Select构建器,还是基本可以满足很多情况的。

$table = new Zend\Db\TableGateway\TableGateway('product',$adapter);


// 从TableGateway返回Sql,再从Sql返回一个Select对象
// 这个Select表名是已知的
// 相对于执行了$select->from($table)
$select = $table->getSql()->select();

/*
$select->where('id > 10')->order('id DESC')->limit(10);

// 然后把这个Select对象丢给TableGateway的selectWith()方法
// selectWith()只接收Select对象,select()方法接收Where对象等
$resultSet = $table->selectWith($select);
print_r($resultSet->toArray());
*/

/*
$select->where(function($where){
    $where->lessThan('id',10);
    $where->greaterThan('id',5);
    return $where;
})->order('id DESC')->limit(10);

$resultSet = $table->selectWith($select);
print_r($resultSet->toArray());
*/

/*
// 获取Select的Where对象,不能用where()方法,因为它是构建where条件
// 所以比较操蛋,绝对的不舒服
$where = $select->where;
$where->lessThan('id',10);
$where->greaterThan('id',5);
$select->order('id DESC')->limit(10);

$resultSet = $table->selectWith($select);
print_r($resultSet->toArray());
*/

// where可以是一个字符串,也可以是一个数组,字符串表示条件一个条件
// 第二参数表示是OR 或  AND,默认为AND,但是第一个where不会添加前置符
// 链式操作可以添加多个条件,是OR 是  AND由后面的where的第二参数决定 
// $sqlSring = $select->where('id > 30','OR')->where('id < 40','OR')->getSqlString();
// SELECT "product".* FROM "product" WHERE id > 30 OR id < 40

// where()方法还可接收一个数组,数组的单元是每个条件,这些条件是OR是AND还是由第二参数决定
// 可以看到,这样搞法很容易引起歧义
// $sqlSring = $select->where(array('id > 30','name like "%vfeelit%"'))->where(array('id > 40'),'OR')->getSqlString();
// SELECT "product".* FROM "product" WHERE id > 30 AND name like "%vfeelit%" OR id > 40

$select->where(function($where){
    $subWhereId = clone $where;
    $subWhereTitle = clone $where;
    
    $subWhereId->lessThan('id',10);
    //$subWhereId->or;
    $subWhereId->greaterThan('id',20);
    $where->addPredicate($subWhereId);
    
    $subWhereTitle->equalTo('title', 'a');
    //$subWhereTitle->or;
    $subWhereTitle->equalTo('title', 'b');
    $where->addPredicate($subWhereTitle);
    
    return $where;
});
// 这就是构建复杂查询的方法,有没有活生生把人气死的感觉?
// addPredicate就是添加一个断言,就是一个整体,用括号括起来
$sqlSring = $select->getSqlString();

注:翻回来看看,Zend Framework这个实现也有点落伍了。3.x不兼容2.x是分分钟有可能的事情。这个官方出品的东西,视乎总无法把握得住发展主流(MVC部分)。不过,它的一些组件个人还是觉得不错的,我也经常使用。DB封装这块,看起来到3.x时,估计也要重写了。