Zend Framework 2db:使用谓词对象使查询的一部分是否定的


Zend Framework 2 Db: Make a part of the query negative using Predicate objects

如何使用Zend Framework 2否定查询的一部分?我试图做Zend'Db等价于这个动态 MySQL查询部分:

NOT (`a` = 1 AND `b`IS NULL AND `c` LIKE 'foo')

现在我有三个查询部分作为谓词对象(Operator, IsNull and Like objects)。我怎么把这些消掉,放在哪里呢?

是否有可能将谓词对象(like an Operator or IsNull object)转换为Sql字符串?

Zend没有现成的解决方案,我写了一个类来做这件事。

/**
 * Created by PhpStorm.
 * User: Exlord (adeli.farhad@gmail.com)
 * Date: 6/19/14
 * Time: 11:44 AM
 */
namespace System'DB'Sql'Predicate;
use Zend'Db'Sql'Predicate'PredicateInterface;
class Not implements PredicateInterface
{
    /**
     * @var string
     */
    protected $specification = 'NOT (%1$s)';
    protected $expression;
    public function __construct($expression = null)
    {
        $this->expression = $expression;
    }
    /**
     * @param null $expression
     */
    public function setExpression($expression)
    {
        $this->expression = $expression;
    }
    /**
     * @return null
     */
    public function getExpression()
    {
        return $this->expression;
    }
    /**
     * @param  string $specification
     * @return self
     */
    public function setSpecification($specification)
    {
        $this->specification = $specification;
        return $this;
    }
    /**
     * @return string
     */
    public function getSpecification()
    {
        return $this->specification;
    }
    /**
     * @return array
     */
    public function getExpressionData()
    {
        return array(
            array($this->specification, array($this->expression), array(self::TYPE_VALUE))
        );
    }
} 

用法:

$where = new Where();
$where->notIn('id', array(1, 2));
$where->equalTo('name', 'Foo');
$select = new Select('tbl_');
$select->where->addPredicate(new Not($where));
var_dump($select->getSqlString());
输出:

string 'SELECT "tbl_"。* WHERE NOT ("id" NOT IN ('1', '2')AND "name" = 'Foo')' (length=81)

更像是-

'a' != 1 AND 'b' IS NOT NULL AND 'c' NOT LIKE 'foo'

尝试这些作为单独的where条件。

,

$where = new Where();
$where->notEqualTo('a', 1);
$where->isNotNull('b');
$where->literal('c NOT LIKE ?', array('foo'));