我正在尝试使用Zend Framework 2在置于不同数据库中的两个表之间建立联接。
第一个表称为用户,并存储在数据库admin
中第二个表称为hierarchy,并存储在数据库customer
中我在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”来自“ users”内联接“ hierarchies” AS“ h” ON“ h”。 “ id” =“用户”。“ idHierarchy” WHERE“ level” ='1'
但是当我尝试使用它时会抛出此异常:
Zend\Db\Adapter\Exception\InvalidQueryException SQLSTATE[42S02]: Base table or view not found: 1146 Table 'admin.hierarchies' doesn't exist
我尝试将数据库的名称指示为int联接,如下所示:
$ 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
有人可以帮我吗?请。
谢谢!
好像是在不久前问过这个问题的,但是我似乎找到了一个很好的解决方法或解决方案。如果您使用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'。您可以用您拥有的任何数据库名称替换它。看看它是否对您有用,对我来说似乎很好。
该框架不支持与另一个数据库的联接。您必须使用普通的SQL来构建查询。
由于Select类对引号进行转义的方式而出现问题。
$ select-> join(“ database2.table2”,“ database2.table2.id = table.id”)
呈现为:
SELECT'table'。*'database2.table2'。* FROM'table'INNER JOIN'database2.table2'ON'database2'。'table2'。'id'='table'。'id'
注意“ database2.table2”周围的不一致和错误的引用。
更新\ Zend \ Db \ Sql \ Select中的第596、599、624、625行以将“ quoteIdentifier”方法替换为“ quoteIdentifierInFragment”可以正确呈现查询并允许执行跨数据库联接。
我已经向Zend提交了一份问题报告,因为我不认为当前行为是故意的,因此希望它将在以后的版本中进行更新。到目前为止,手动更新类已经足够容易了(尽管有些脏)。
Dan回答了,但对于Zend 2.3
为什么使用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);