使用tableadapter时如何在zend3中连接表?问题不在于如何一般地连接表,而是关于如何在zend中执行此操作以及在何处放置代码。
让我们说我有一个*表类,例如:
namespace Import\Model;
use RuntimeException;
use Zend\Db\TableGateway\TableGatewayInterface;
class ProjectTable
{
private $tableGateway='t_project';
public function __construct(TableGatewayInterface $tableGateway)
{
$this->tableGateway = $tableGateway;
}
public function fetchAll()
{
return $this->tableGateway->select();
}
我想加入两张桌子,我怎么能这样做,这里是不是正确的地方?我试图实现以下功能:
public function Project_Unit(Unit $unit = null){
$select = $this->tableGateway->getSql()->select()
->join('t_unit', 't_project.ProjectID = t_unit.ProjectID',array('UnitID','CI_Number', 'Unitname','Shortcut','Suppliername')); //, left
return $this->tableGateway->selectWith($select);
}
我没有收到错误,而是混淆了数据。之后,我尝试使用别名也没有用。
我的问题是,如果我需要连接两个表,如何构建这个表类。表格将是项目1 - > n单位(关键项目ID)。第二个问题是如何正确使用别名,因为我在两个表中都有一些具有不同数据的字段名,例如每个表都有一个列快捷方式。
编辑:新信息 为了查看数据的来源,我重命名了我的Exchangearray的变量:
public function exchangeArray(array $data)
{
$this->PProjectID= !empty($data['ProjectID']) ? $data['ProjectID'] : null;
$this->PCI_Number= !empty($data['CI_Number']) ? $data['CI_Number'] : null;
$this->PDescription= !empty($data['Description']) ? $data['Description'] : null;
$this->Projectname= !empty($data['Projectname']) ? $data['Projectname'] : null;
$this->PShortcut= !empty($data['Shortcut']) ? $data['Shortcut'] : null;
$this->PComponent_Class= !empty($data['Component_Class']) ? $data['Component_Class'] : null;
}
现在我得到一个有趣的输出(我也添加了我的dataarray的内容)
我有两个名称相同的列,它们是快捷方式和ci-number,这些数据字段与tableadapter表中的相同数据字段混合在一起。
U1不是伽利略的捷径,它是单位的捷径。伽利略的捷径应该是GAL。似乎第二个表(单位)填充了名称相同的列,但我不会从表格单元中获取任何字段。
编辑:显示我从求职者的消费中得到的补充:
我编辑了ProjectTable类:
class ProjectTable
{
//private $tableGateway='t_project';
private $projectTableGateway;
private $unitTableGateway;
// public function __construct(TableGatewayInterface $tableGateway)
// {
// $this->tableGateway = $tableGateway;
// }
public function __construct(
TableGatewayInterface $projectTableGateway,
TableGatewayInterface $unitTableGateway)
{
$this->projectTableGateway = $projectTableGateway;
$this->unitTableGateway = $unitTableGateway;
}
public function fetchAll()
{
$sqlSelect = $this->unitTableGateway->getSql()->select();
/**
* columns for the "project_table" exactly it is unit_table
*/
$sqlSelect->columns(array('CI_Number', 'ProjectID','Unitname','Shortcut','Suppliername'));
/**
* this can take two more arguments:
* an array of columns for "unit_table"
* and a join type, such as "inner"
*/
$sqlSelect->join('t_project', 't_unit.ProjectID = t_project.ProjectID');
/**
* set condition based on columns
*/
//$sqlSelect->where(array('unit_table.project_id' => $id));
$resultSet = $this->unitTableGateway->selectWith($sqlSelect);
return $resultSet;
//return $this->tableGateway->select();
}
我也像我建议的那样编辑了我的Module.php,这里有一个片段
// Model\ProjectTable::class => function($container) {
// $tableGateway = $container->get(Model\ProjectTableGateway::class);
// return new Model\ProjectTable($tableGateway);
// },
Model\ProjectTable::class => function($container) {
$projectTableGateway = $container->get(Model\ProjectTableGateway::class);
$unitTableGateway = $container->get(Model\UnitTableGateway::class);
return new Model\ProjectTable($projectTableGateway, $unitTableGateway);
},
Model\ProjectTableGateway::class => function ($container) {
$dbAdapter = $container->get(AdapterInterface::class);
$resultSetPrototype = new ResultSet();
$resultSetPrototype->setArrayObjectPrototype(new Model\Project());
return new TableGateway('t_project', $dbAdapter, null, $resultSetPrototype);
}
我的控制器操作没有改变:
return new ViewModel([
'projects' => $this->projectTable->fetchAll(),
]);
在我看来,我试图抓住两个表的列:
foreach ($projects as $project) :
// $unit=$units->fetchAllP($project->ProjectID);
var_dump(get_object_vars($project));?>
<tr>
<td><?= $this->escapeHtml($project->Unitname) ?></td>
<td><?= $this->escapeHtml($project->Projectname) ?></td>
<td><?= $this->escapeHtml($project->Shortcut) ?></td>
<td><?= $this->escapeHtml($project->CI_Number) ?></td>
<td><?= $this->escapeHtml($project->Description) ?></td>
<td><?= $this->escapeHtml($project->Component_Class) ?></td>
<td>
<a href="<?= $this->url('project', ['action' => 'edit', 'id' => $project->ProjectID]) ?>">Edit</a>
<a href="<?= $this->url('project', ['action' => 'delete', 'id' => $project->ProjectID]) ?>">Delete</a>
</td>
<?php endforeach; ?>
我得到了一个有趣的输出,所以仍然缺少某些东西。我希望两个联合表中都有al列。
EDIT2:显示下一个版本
这是我的方法fetchAll()/ class ProjectTable
public function fetchAll()
{
$sqlSelect = $this->unitTableGateway->getSql()->select();
$sqlSelect->columns(array('UnitID','CI_Number', 'ProjectID','Unitname','Shortcut','Suppliername'));
$sqlSelect->join('t_project', 't_unit.ProjectID = t_project.ProjectID', array('Project' =>'Projectname','CI' =>'CI_Number','PDescription' =>'Description','PShortcut' =>'Shortcut','PComponent' =>'Component_Class','PProjectID' =>'ProjectID'));
//$sqlSelect->where(array('unit_table.project_id' => $id));
$resultSet = $this->unitTableGateway->selectWith($sqlSelect);
//return $resultSet;
return $resultSet->toArray();
//return $this->tableGateway->select();
这是我的观点:
<?php
//var_dump(get_object_vars($projects));
foreach ($projects as $project) :
//var_dump(get_object_vars($project));
?>
<tr>
<td><?= $project['Project']?></td>
<td><?= $project['CI']?></td>
<td><?= $project['Unitname']?></td>
<?php
endforeach; ?>
}
EDIT3:添加单位资料
class UnitTable
{
private $tableGateway='t_unit';
public function __construct(TableGatewayInterface $tableGateway)
{
$this->tableGateway = $tableGateway;
}
public function fetchAll()
{
return $this->tableGateway->select();
}
班级单位:
class Unit implements InputFilterAwareInterface
{
public $UnitID;
public $CI_Number;
public $ProjectID;
public $Unitname;
public $Shortcut;
public $Suppliername;
private $inputFilter;
public function exchangeArray(array $data)
{
$this->UnitID= !empty($data['UnitID']) ? $data['UnitID'] : null;
$this->CI_Number= !empty($data['CI_Number']) ? $data['CI_Number'] : null;
$this->ProjectID= !empty($data['ProjectID']) ? $data['ProjectID'] : null;
$this->Unitname= !empty($data['Unitname']) ? $data['Unitname'] : null;
$this->Shortcut= !empty($data['Shortcut']) ? $data['Shortcut'] : null;
$this->Suppliername= !empty($data['Suppliername']) ? $data['Suppliername'] : null;
}
因为我还有抽样数据,我的两个表单元和项目的截图
EDIT4:module.php的工厂部分
public function getServiceConfig()
{
return [
'factories' => [
Model\ImportTable::class => function($container) {
$tableGateway = $container->get(Model\ImportTableGateway::class);
return new Model\ImportTable($tableGateway);
},
Model\ImportTableGateway::class => function ($container) {
$dbAdapter = $container->get(AdapterInterface::class);
$resultSetPrototype = new ResultSet();
$resultSetPrototype->setArrayObjectPrototype(new Model\Import());
return new TableGateway('t_dcl', $dbAdapter, null, $resultSetPrototype);
},
Model\DclimportTable::class => function($container) {
$tableGateway = $container->get(Model\DclimportTableGateway::class);
return new Model\DclimportTable($tableGateway);
},
Model\DclimportTableGateway::class => function ($container) {
$dbAdapter = $container->get(AdapterInterface::class);
$resultSetPrototype = new ResultSet();
$resultSetPrototype->setArrayObjectPrototype(new Model\Dclimport());
return new TableGateway('t_dcl_import', $dbAdapter, null, $resultSetPrototype);
},
Model\FollowupTable::class => function($container) {
$tableGateway = $container->get(Model\FollowupTableGateway::class);
return new Model\FollowupTable($tableGateway);
},
Model\FollowupTableGateway::class => function ($container) {
$dbAdapter = $container->get(AdapterInterface::class);
$resultSetPrototype = new ResultSet();
$resultSetPrototype->setArrayObjectPrototype(new Model\Followup());
return new TableGateway('t_dcl_wv', $dbAdapter, null, $resultSetPrototype);
},
Model\UnitTable::class => function($container) {
$tableGateway = $container->get(Model\UnitTableGateway::class);
return new Model\UnitTable($tableGateway);
},
Model\UnitTableGateway::class => function ($container) {
$dbAdapter = $container->get(AdapterInterface::class);
$resultSetPrototype = new ResultSet();
$resultSetPrototype->setArrayObjectPrototype(new Model\Unit());
return new TableGateway('t_unit', $dbAdapter, null, $resultSetPrototype);
},
// Model\ProjectTable::class => function($container) {
// $tableGateway = $container->get(Model\ProjectTableGateway::class);
// return new Model\ProjectTable($tableGateway);
// },
Model\ProjectTableGateway::class => function ($container) {
$dbAdapter = $container->get(AdapterInterface::class);
$resultSetPrototype = new ResultSet();
$resultSetPrototype->setArrayObjectPrototype(new Model\Project());
return new TableGateway('t_project', $dbAdapter, null, $resultSetPrototype);
},
Model\ProjectTable::class => function($container) {
$projectTableGateway = $container->get(Model\ProjectTableGateway::class);
$unitTableGateway = $container->get(Model\UnitTableGateway::class);
return new Model\ProjectTable($projectTableGateway, $unitTableGateway);
}
],
];
}
答案 0 :(得分:1)
如果您知道如何处理模型中的两个表,这非常简单。假设您拥有ProjectTable
和UnitTable
个模型以及两个TableGateway
服务。那些将分别处理数据库中的两个表。因此,如果您想在ProjectTable
模型中加入它们,那么
ProjectTable.php
class ProjectTable
{
private $projectTableGateway;
private $unitTableGateway;
public function __construct(
TableGatewayInterface $projectTableGateway,
TableGatewayInterface $unitTableGateway)
{
$this->projectTableGateway = $projectTableGateway;
$this->unitTableGateway = $unitTableGateway;
}
public function projectUnit($id)
{
/**
* as you are joing with "project_table"
* this will handle "unit_table"
*/
$sqlSelect = $this->unitTableGateway->getSql()->select();
/**
* columns for the "unit_table".
* if want to use aliases use as
* array('alias_name' => 'column_name')
*/
$sqlSelect->columns(array('column_one', 'column_two'));
/**
* this can take two more arguments:
* an array of columns for "project_table"
* and a join type, such as "inner"
*/
$sqlSelect->join('project_table', 'unit_table.project_id = project_table.id');
/**
* set condition based on columns
*/
$sqlSelect->where(array('unit_table.project_id' => $id));
$resultSet = $this->unitTableGateway->selectWith($sqlSelect);
return $resultSet;
}
}
现在创建两个TableGateway
服务来处理两个表,并将它们传递给ProjectTable
的构造函数,如下所示
Model\ProjectTable::class => function($container) {
$projectTableGateway = $container->get(Model\ProjectTableGateway::class);
$unitTableGateway = $container->get(Model\UnitTableGateway::class);
return new Model\ProjectTable($projectTableGateway, $unitTableGateway);
}
答案 1 :(得分:0)
我认为你错过了这一点。您无法访问操纵表网关的表。您应该做的是使用表格网关,这样您就不必再处理表格和SQL了。因此模式的名称为Table Gateway。
了解ZF manual describes this的方式。
完成此操作后,可以轻松地将两个表连接到表网关的单个方法之后。此方法返回一个完全从数据库概念中删除的模型。