强制 Model::find() 在 CakePHP 中重用准备好的语句

Force Model::find() to reuse a prepared statement in CakePHP

原始 PHP 我会这样做:

$sth = $dbh->prepare("SELECT * FROM tags WHERE tag=:tag");

foreach ( $tags as $tag ) {
    $sth->bindValue(':tag', $tag);
    $sth->execute(); // followed by fetch, etc.
}

在 CakePHP 中,我必须使用本机 find() 函数:

foreach ( $tags as $tag ) {
    $this->Tag->find('first', array(
        'conditions' => array(
            'tag' => $tag,
        ),
    ));
}

我很确定这会导致 CakePHP 触发一组不使用 the benefits of having the prepared statement in place.

的独立数据库查询

有什么方法可以强制 CakePHP 在不修改核心的情况下这样做吗?

更新 There is a way to call $this->getDataSource() directly but I'm looking for a way to keep using the find() method, if possible, because it handles contains automatically and the code for those complex queries using joins 这样看起来就更优雅了。

您需要创建一个 custom/extended 数据源,and/or 一个自定义连接 class,两者都可以实现适当的缓存机制。

在数据源级别,您必须重新实现 DboSource::_execute()。在连接级别上,您必须覆盖 PDO::prepare().

看看 DboSource::_execute() 目前在做什么:

https://github.com/cakephp/.../blob/2.7.9/lib/Cake/Model/Datasource/DboSource.php#L448

它会在每次被调用时创建一个新的语句,并且在不重新实现整个方法的情况下挂钩的唯一方法是使用自定义连接 ($this->_connection)。

但是,为了能够使用自定义连接 class,您必须重新实现 connect() 方法(由单独的 DBO 驱动程序实现 class es),这也不是一件好事。

https://github.com/cakephp/.../blob/2.7.9/lib/Cake/Model/Datasource/Database/Mysql.php#L152

另见 Cookbook > Models > DataSources

Cake 已经在 DboSource class 中为您做您想做的事了。

Just read the code of it.