zf2在两个不同的数据库之间建立连接

时间:2013-04-05 09:48:53

标签: zend-framework2 zend-db zend-db-table

我正在尝试使用Zend Framework 2在两个表之间建立连接。

第一个表名为用户,存储在数据库 admin

第二个表名为层次结构,存储在数据库客户

我在global.php中加载数据库适配器

return array(
'admin' => array(
    'driver' => 'Pdo',
    'dsn' => 'mysql:dbname=admin;host=localhost',
    'driver_options' => array(
        PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
    ),
),
'customer' => array(
    'driver' => 'Pdo',
    'dsn' => 'mysql:dbname=customer;host=localhost',
    'driver_options' => array(
        PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
    ),
),
'service_manager' => array(
    'factories' => array(
        'Zend\Db\Adapter\Adapter'
        => 'Zend\Db\Adapter\AdapterServiceFactory',
    ),
),
     

);

但是当我尝试使用此功能在UserDao中进行连接时:

public function getSelect(Hierarchy $hierarchy) {
    $select = $this->tableGateway->getSql()->select();
    $select->where(array('level' => $hierarchy()->getId()));
    $select->join(array('h' => 'hierarchies'), 'h.id = users.idHierarchy', array('hierarchyId' => 'id', 'level' => 'level'));
    return $select;
}

这会产生这个SQL句子:

  

SELECT“users”。*,“h”。“id”AS“hierarchyId”,“h”。“level”AS“level”FROM“users”INNER JOIN“hierarchyies”AS“h”ON“h” 。“id”=“users”。“idHierarchy”WHERE“level”='1'

但是当我尝试使用它时会抛出此异常:

Zend\Db\Adapter\Exception\InvalidQueryException
SQLSTATE[42S02]: Base table or view not found: 1146 Table 'admin.hierarchies' doesn't exist

我尝试在连接中指示数据库的名称,如下所示:

  

$ select-> join(array('h'=>'customer.hierarchies'),'h.id = users.idHierarchy',array('hierarchyId'=>'id','level' =>'level'));

但它也抛出了这个例外:

  

SQLSTATE [42S02]:未找到基表或视图:1146表'admin.customer.hierarchies'不存在

我发现这个网站解释了我如何做到这一点,但它只对Zend Framework 1有效,而且我正在使用Zend Framework 2.

Using Different Databases with Zend Framework

有人能帮帮我吗?请。

谢谢!

5 个答案:

答案 0 :(得分:3)

这个问题似乎被问到了一段时间,但我似乎找到了一个很好的解决方法或解决方案。如果您使用Zend \ Db \ Sql \ TableIdentifier和Zend \ Db \ Sq \ Expression,您将能够解决您的问题。

public function getSelect(Hierarchy $hierarchy) {
    $select = $this->tableGateway->getSql()->select();
    $select->where(array('level' => $hierarchy()->getId()));
    $select->join(
         array('h' => new TableIdentifier('hierarchies', 'admin')), 
         new Expression('h.id = ?', 'users.idHierarchy', Expression::TYPE_IDENTIFIER), 
         array('hierarchyId' => 'id', 'level' => 'level')
    );
    return $select;
}

我不确定您的层次结构表所在的数据库,所以我现在使用'admin'。你可以用你拥有的数据库名称替换它。看看它是否适合你,似乎对我有用。

答案 1 :(得分:0)

该框架不支持与其他数据库的连接。您必须使用纯SQL来构建查询。

答案 2 :(得分:0)

由于Select类转义引号的方式,问题正在发生。

$ select-> join(“database2.table2”,“database2.table2.id = table.id”)

呈现为:

SELECT'table'。*'database2.table2'。* FROM'table'INNER JOIN'inatabase2.table2'ON'database2'.'table2'.'id'='table'.'id'

请注意“database2.table2”周围的引用不一致和不正确。

更新\ Zend \ Db \ Sql \ Select中的第596,599,624,625行,用“quoteIdentifierInFragment”替换“quoteIdentifier”方法,可以正确呈现查询,并允许执行跨数据库连接。

我已经向Zend提交了一份问题报告,因为我不相信当前的行为是有意的,所以希望它将在未来的构建中更新。现在,手动更新类很容易(尽管有点脏)。

https://github.com/zendframework/zf2/issues/4307

答案 3 :(得分:0)

正如Dan已回答,但对于 Zend 2.3 ,您应该更改文件 Zend \ Db \ Sql \ Select.php 中的第742行

$joinName = $platform->quoteIdentifier($joinName);

$joinName = $platform->quoteIdentifierInFragment($joinName);
来自

第680行

$name = $platform->quoteIdentifier($name);

$name = $platform->quoteIdentifierInFragment($name);


Obs:这些只是我能识别的行,可能不是一个完整的列表。

答案 4 :(得分:0)

为什么要使用DAO概念?只有在表网关中,您才能拥有所有需要的东西。您已经在global或local.php中具有适配器。您已经有用于表网关的工厂,不是吗?为什么需要将Hierarchy类(我认为这是另一个表网关)传递给当前类?要进行所需的联接,唯一需要的就是表标识符。

$table2 = new Zend\Db\Sql\TableIdentifier('table2', 'schema_name'); 
$select = $this->tableGateway->getSql()->select()
->join($table2, 'table1.field = table2.field', ['fields_from_table2'], 'INNER');

$sql = new Sql($this->tableGateway->getAdapter());
$selectString = $sql->buildSqlString($select);
$result = $adapter->query($selectString, $adapter::QUERY_MODE_EXECUTE);

See the answer for this question