CRUD是指增加(Create)、读取(Retrieve)、更新(Update)和删除(Delete)几个单词的首字母简写。
在ZendFramework2项目中建立一个模块Test。
Test模块的module.config.php的控制器和路由这样配置:
<span style="font-size:18px;"> 'controllers' => array(
'invokables' => array(
'Test\Controller\Test' => 'Test\Controller\TestController',
),
),
'router' => array(
'routes' => array(
'test' => array(
'type' => 'segment',
'options' => array(
'route' => '/test[/][:action][/:id]',
'constraints' => array(
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'id' => '[0-9]+',
),
'defaults' => array(
'controller' => 'Test\Controller\Test',
'action' => 'tdb',
),
),
),
),
),</span>
一)单表单对象的CRUD操作
在数据库中创建这样一个表:
CREATE TABLE `a` (
`name` varchar(255) NOT NULL,
`content` varchar(255) DEFAULT NULL,
PRIMARY KEY (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
单表单对象的CRUD操作实现起来相对简单,可以参考ZendFramework2的例子程序Album模块。
在Modules\Test\src\Model\下创建文件“A.php”和“ATable.php”
A.php内容如下:
namespace Test\Model;
class A {
public $name;
public $content;
public $type;
public function __construct() {
}
public function exchangeArray($data) {
$this->name = empty($data['name']) ? null : $data['name'];
$this->content = empty($data['content']) ? null : $data['content'];
$this->type = empty($data['type']) ? null : $data['type'];
}
//binding Model to Form needs this method
public function getArrayCopy() {
return get_object_vars($this);
}
}
其中exchangeArray函数会被框架调用,其参数$data是一个从表a获取的以表a的字段名/字段值为key/value的关联数组,该函数用于填充对象。
其中getArrayCopy函数是将对象按对象属性/属性值为key/value转换为关联数组。
ATable.php类容如下:
namespace Test\Model;
use Zend\Db\TableGateway\TableGateway;
use Zend\Db\Sql\Where;
use Zend\Db\Sql\Predicate\Operator;
class ATable {
protected $tableGateway;
public function __construct(TableGateway $tableGateway) {
$this->tableGateway = $tableGateway;
}
public function select($where=null) {
$resultSet = $this->tableGateway->select($where);
return $resultSet;
}
public function update($a) {
if (!($a instanceof A)) {
return false;
}
//检查要修改的记录主键是否存在
$where = new Where();
$where->addPredicate(new Operator('name', Operator::OPERATOR_EQUAL_TO, $a->name));
$resultSet = $this->tableGateway->select($where);
if (count($resultSet) > 0) {
$data = $a->getArrayCopy();
unset($data['name']);//移除主键
try {
$ret = $this->tableGateway->update($data, array('name' => $a->name));
if ($ret == 1 || $ret == 0) {
return true;
}
} catch (Exception $ex) {
}
}
return false;
}
public function insert($a) {
if (!($a instanceof A)) {
return false;
}
//检查要修改的记录主键是否存在
$where = new Where();
$where->addPredicate(new Operator('name', Operator::OPERATOR_EQUAL_TO, $a->name));
$resultSet = $this->tableGateway->select($where);
if (count($resultSet) > 0) {
return false;
}
try {
$data = $a->getArrayCopy();
$ret = $this->tableGateway->insert($data);
if ($ret == 1) {
return true;
}
} catch (Exception $ex) {
}
return false;
}
public function delete($a) {
if (!($a instanceof A)) {
return false;
}
try {
$ret = $this->tableGateway->delete(array('name' => $a->name));
if ($ret == 1) {
return true;
}
} catch (Exception $ex) {
}
return false;
}
}
该类是表a的操作类,具体实现select、update、delete、insert操作。
打开Module\Test\Module.php文件,添加getServiceConfig函数:
public function getServiceConfig()
{
return array(
'factories' => array(
'Test\Model\ATable' => function($sm) {
$tableGateway = $sm->get('ATableGateway');
$table = new ATable($tableGateway);
return $table;
},
'ATableGateway' => function ($sm) {
$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
$resultSetPrototype = new ResultSet();
$resultSetPrototype->setArrayObjectPrototype(new A());
return new TableGateway('a', $dbAdapter, null, $resultSetPrototype);
},
);
}
其中,ResultSet->setArrayObjectPrototype就是执行ATable->select函数时,ZendFramework2框架自动将表记录转换为的对象原型。
并添加类引用:
use Test\Model\A;
use Test\Model\ATable;
在Module\Test\src\Test\Controller\TestController.php中添加对象A的CRUD四个控制器:
namespace Test\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
use Zend\Db\Sql\Where;
use Zend\Db\Sql\Predicate\Operator;
use Test\Model\A;
class TestController extends AbstractActionController {
protected $aTable;
public function getATable() {
if (!$this->aTable) {
$sm = $this->getServiceLocator();
$this->aTable = $sm->get('Test\Model\ATable');
}
return $this->aTable;
}
public function selectAction() {
$name = $this->params()->fromQuery('name');
if (!empty($name)) {
$where = new Where();
$where->addPredicate(new Operator('name', Operator::OPERATOR_EQUAL_TO, $name));
}
return new ViewModel(array(
'as' => $this->getATable()->select((isset($where)?$where:null)),
));
}
public function insertAction() {
$name = $this->params()->fromQuery('name');
if (empty($name)) {
$name = 'name';
}
$a = new A;
$a->name = $name;
$a->content = "content";
$ret = $this->getATable()->insert($a);
return new ViewModel(array(
'ret' => ($ret==false?"false":"true"),
));
}
public function updateAction() {
$name = $this->params()->fromQuery('name');
if (empty($name)) {
$name = 'name';
}
$content = $this->params()->fromQuery('content');
if (empty($content)) {
$content = 'content';
}
$a = new A;
$a->name = $name;
$a->content = $content;
$ret = $this->getATable()->update($a);
return new ViewModel(array(
'ret' => ($ret==false?"false":"true"),
));
}
public function deleteAction() {
$name = $this->params()->fromQuery('name');
if (empty($name)) {
$name = 'name';
}
$a = new A;
$a->name = $name;
$ret = $this->getATable()->delete($a);
return new ViewModel(array(
'ret' => ($ret==false?"false":"true"),
));
}
}
最后在Module\Test\view\test\test\目录下新建select.phtml、insert.phtml、update.phtml和delete.phtml:
//select.phtml
$title = 'select';
$this->headTitle($title);
?>
<h1><?php echo $this->escapeHtml($title); ?></h1>
<?php
foreach ($this->as as $a) {
echo $this->escapeHtml($a->name);
echo "------";
echo $this->escapeHtml($a->content);
echo "<br/>";
}
//insert.phtml
$title = 'insert';
$this->headTitle($title);
?>
<h1><?php echo $this->escapeHtml($title); ?></h1>
<?php
echo $this->ret;
echo "<br/>";
//update.phtml
$title = 'update';
$this->headTitle($title);
?>
<h1><?php echo $this->escapeHtml($title); ?></h1>
<?php
echo $this->ret;
echo "<br/>";
//delete.phtml
$title = 'delete';
$this->headTitle($title);
?>
<h1><?php echo $this->escapeHtml($title); ?></h1>
<?php
echo $this->ret;
echo "<br/>";
读取(Retrieve)使用http://xxxx/test/select或者http://xxx/test/select?name=y。
增加(Create)使用http://xxx/test/insert?name=y。
更新(Update)使用http://xxx/test/insert?name=y&content=z。
删除(Delete)使用http://xxx/test/delete?name=y。
二)单表多对象的CRUD操作
假设有这样一种类关系:class b;为基类,class B1;和class B2;分别各自从class b;继承,而B1和B2的对象存入数据库时,都是存在一张表里面,这种情况下,一张表的记录record就可能转换为B1和B2多种类的对象。
在数据库中创建这样一个表:
CREATE TABLE `b` (
`name` varchar(255) NOT NULL,
`content` varchar(255) DEFAULT NULL,
`type` varchar(40) DEFAULT NULL,//type=='B1'代表是B1存储而来,type=='B2'代表是B2存储而来
`contentB1` varchar(255) DEFAULT NULL,
`contentB2` varchar(255) DEFAULT NULL,
PRIMARY KEY (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
在Modules\Test\src\Model\下创建文件“B.php”、“B1.php”、“B2.php”和“BTable.php”
B.php内容如下:
namespace Test\Model;
class B {
public $name;
public $content;
public $type;
public function __construct() {
}
public function exchangeArray($data) {
$this->name = empty($data['name']) ? null : $data['name'];
$this->content = empty($data['content']) ? null : $data['content'];
$this->type = empty($data['type']) ? null : $data['type'];
}
public function getArrayCopy() {
return get_object_vars($this);
}
}
B1.php内容如下:
namespace Test\Model;
use Test\Model\B;
class B1 extends B{
public $contentB1;
public function __construct() {
}
public function exchangeArray($data) {
parent::exchangeArray($data);
$this->contentB1 = empty($data['contentB1']) ? null : $data['contentB1'];
}
public function getArrayCopy() {
return get_object_vars($this);
}
}
B2.php内容如下:
namespace Test\Model;
use Test\Model\B;
class B2 extends B{
public $contentB2;
public function __construct() {
}
public function exchangeArray($data) {
parent::exchangeArray($data);
$this->contentB2 = empty($data['contentB2']) ? null : $data['contentB2'];
}
public function getArrayCopy() {
return get_object_vars($this);
}
}
BTable.php内容如下:
namespace Test\Model;
use Zend\Db\TableGateway\TableGateway;
use Zend\Db\Sql\Where;
use Zend\Db\Sql\Predicate\Operator;
use Test\Model\B;
use Test\Model\B1;
use Test\Model\B2;
class BTable {
protected $tableGateway;
public function __construct(TableGateway $tableGateway) {
$this->tableGateway = $tableGateway;
}
public function select($where=null) {
$resultSet = $this->tableGateway->select($where);
//由于module.php里面指定返回的是关联数组,因此此处要编写关联数组转为对象数组的代码
$resultSetObjs = array();
foreach ($resultSet as $rec) {
$type = $rec['type'];
if (empty($type)) {
$obj = new B();
} else if ($type == 'B1') {
$obj = new B1();
} else {
$obj = new B2();
}
$obj->exchangeArray($rec);
$resultSetObjs[] = $obj;
}
return $resultSetObjs;
}
public function update($b) {
if (!($b instanceof B) &&
!($b instanceof B1) &&
!($b instanceof B2)) {
return false;
}
//检查要修改的记录主键是否存在
$where = new Where();
$where->addPredicate(new Operator('name', Operator::OPERATOR_EQUAL_TO, $b->name));
$resultSet = $this->tableGateway->select($where);
if (count($resultSet) > 0) {
$data = $b->getArrayCopy();
unset($data['name']);//移除主键
try {
$ret = $this->tableGateway->update($data, array('name' => $b->name));
if ($ret == 1 || $ret == 0) {
return true;
}
} catch (Exception $ex) {
}
}
return false;
}
public function insert($b) {
if (!($b instanceof B) &&
!($b instanceof B1) &&
!($b instanceof B2)) {
return false;
}
//检查要修改的记录主键是否存在
$where = new Where();
$where->addPredicate(new Operator('name', Operator::OPERATOR_EQUAL_TO, $b->name));
$resultSet = $this->tableGateway->select($where);
if (count($resultSet) > 0) {
return false;
}
try {
$data = $b->getArrayCopy();
$ret = $this->tableGateway->insert($data);
if ($ret == 1) {
return true;
}
} catch (Exception $ex) {
}
return false;
}
public function delete($b) {
if (!($b instanceof B) &&
!($b instanceof B1) &&
!($b instanceof B2)) {
return false;
}
try {
$ret = $this->tableGateway->delete(array('name' => $b->name));
if ($ret == 1) {
return true;
}
} catch (Exception $ex) {
}
return false;
}
}
打开Module\Test\Module.php文件,修改getServiceConfig函数:
public function getServiceConfig()
{
return array(
'factories' => array(
'Test\Model\ATable' => function($sm) {
$tableGateway = $sm->get('ATableGateway');
$table = new ATable($tableGateway);
return $table;
},
'ATableGateway' => function ($sm) {
$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
$resultSetPrototype = new ResultSet();
$resultSetPrototype->setArrayObjectPrototype(new A());
return new TableGateway('a', $dbAdapter, null, $resultSetPrototype);
},
'Test\Model\BTable' => function($sm) {
$tableGateway = $sm->get('BTableGateway');
$table = new BTable($tableGateway);
return $table;
},
'BTableGateway' => function ($sm) {
$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
//指定结果集是array,就可以阻止tableGateway将结果集的记录映射成对象
//这是就需要在BTable的select函数里手动将数组转换为对象
$resultSetPrototype = new ResultSet(ResultSet::TYPE_ARRAY);
return new TableGateway('a', $dbAdapter, null, $resultSetPrototype);
},
),
);
}
其中new ResultSet(ResultSet::TYPE_ARRAY);TYPE_ARRAY的作用是让ZendFramework2框架将结果集作为关联数组返回,之后就可以在BTable里面通过代码将记录集转换为不同对象了。
在Module\Test\src\Test\Controller\TestController.php中添加对象B、B1、B2的CRUD四个控制器:
class TestController extends AbstractActionController {
protected $bTable;
public function getBTable() {
if (!$this->bTable) {
$sm = $this->getServiceLocator();
$this->bTable = $sm->get('Test\Model\BTable');
}
return $this->bTable;
}
public function selectbAction() {
$name = $this->params()->fromQuery('name');
if (!empty($name)) {
$where = new Where();
$where->addPredicate(new Operator('name', Operator::OPERATOR_EQUAL_TO, $name));
}
$resultSet = $this->getBTable()->select((isset($where)?$where:null));
return new ViewModel(array(
'bs' => $resultSet,
));
}
public function deletebAction() {
$name = $this->params()->fromQuery('name');
if (empty($name)) {
$name = 'name';
}
$b = new B;
$b->name = $name;
$ret = $this->getBTable()->delete($b);
return new ViewModel(array(
'ret' => ($ret==false?"false":"true"),
));
}
public function updatebAction() {
$name = $this->params()->fromQuery('name');
if (empty($name)) {
$name = 'name';
}
$b = new B1;
$b->name = $name;
$b->content = 'new content';
$b->type = 'B1';
$b->contentB1 = 'B1';
/*
$b = new B2;
$b->name = $name;
$b->content = 'new content';
$b->type = 'B2';
$b->contentB2 = 'B2';
*/
$ret = $this->getBTable()->update($b);
return new ViewModel(array(
'ret' => ($ret==false?"false":"true"),
));
}
public function insertbAction() {
$name = $this->params()->fromQuery('name');
if (empty($name)) {
$name = 'name';
}
$b = new B2;
$b->name = $name;
$b->content = "b2 content";
$b->type = 'B2';
$b->contentB2 = 'B2';
/*
$b = new B2;
$b->name = $name;
$b->content = "b2 content";
$b->type = 'B2';
$b->contentB2 = 'B2';
*/
$ret = $this->getATable()->insert($b);
return new ViewModel(array(
'ret' => ($ret==false?"false":"true"),
));
}
}
同时记得添加引用:
use Test\Model\B;
use Test\Model\B1;
use Test\Model\B2;
最后在Module\Test\view\test\test\目录下新建selectb.phtml、insertb.phtml、updateb.phtml和deleteb.phtml:
//selectb.phtml
$title = 'selectB';
$this->headTitle($title);
?>
<h1><?php echo $this->escapeHtml($title); ?></h1>
<?php
foreach ($this->bs as $b) {
echo $this->escapeHtml($b->name);
echo "------";
echo $this->escapeHtml($b->content);
echo "------";
echo $this->escapeHtml($b->type);
echo "------get_class:";
echo $this->escapeHtml(get_class($b));
echo "<br/>";
}
//insertb.phtml
$title = 'insertB';
$this->headTitle($title);
?>
<h1><?php echo $this->escapeHtml($title); ?></h1>
<?php
echo $this->ret;
echo "<br/>";
//updateb.phtml
$title = 'updateB';
$this->headTitle($title);
?>
<h1><?php echo $this->escapeHtml($title); ?></h1>
<?php
echo $this->ret;
echo "<br/>";
//deleteb.phtml
$title = 'deleteB';
$this->headTitle($title);
?>
<h1><?php echo $this->escapeHtml($title); ?></h1>
<?php
echo $this->ret;
echo "<br/>";
读取(Retrieve)使用http://xxxx/test/selectb或者http://xxx/test/selectb?name=y。
增加(Create)使用http://xxx/test/insertb?name=y。
更新(Update)使用http://xxx/test/insertb?name=y。
删除(Delete)使用http://xxx/test/deleteb?name=y。
三)多表单对象的CRUD操作
假设有这样一种类关系:class Main;类中有个数组protected $path = array();将Main对象存入数据库时,可能将$path单独存入一张assisttable表,这样情况下,多张表的多条记录records才转成类Main的一个对象。
在数据库中创建2张表:
CREATE TABLE `maintable` (
`name` varchar(255) NOT NULL,
`content` varchar(255) DEFAULT NULL,
PRIMARY KEY (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `assisttable` (
`mainName` varchar(255) NOT NULL,
`path` varchar(255) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
maintable表的name字段和assisttable的mainName字段是一对多的关系。
在Modules\Test\src\Model\下创建文件“Main.php”、“MainTable.php”和“MaintableFeature.php“。
Main.php内容如下:
namespace Test\Model;
class Main {
public $name;
public $content;
public $path = array();
public function __construct() {
}
public function getArrayCopy() {
return get_object_vars($this);
}
}
其中类Main没有实现exchangeArray函数。
MainTable.php内容如下:
namespace Test\Model;
use Zend\Db\TableGateway\TableGateway;
use Zend\Db\Sql\Where;
use Zend\Db\Sql\Predicate\Operator;
use Zend\Db\Sql\Sql;
use Zend\Db\Sql\Select;
use Test\Model\Main;
class MainTable {
protected $tableGateway;
public function __construct(TableGateway $tableGateway) {
$this->tableGateway = $tableGateway;
}
public function select($where=null) {
$selectFeature = new MaintableFeature('assisttable');
$selectFeature->setParamsForSelect('maintable.name=assisttable.mainName');
$this->tableGateway->getFeatureSet()->addFeature($selectFeature);
$resultSet = $this->tableGateway->select($where);
//将结果集转换为对象数组
$count = 1;
$nameArray = array();
$objectArray = array();
foreach ($resultSet as $rec){
$key = array_search($rec['name'], $nameArray);
if (empty($key)) {
$nameArray[$count] = $rec['name'];
$objectArray[$count] = new Main();
$objectArray[$count]->name = $rec['name'];
$objectArray[$count]->content = (empty($rec['content'])?null:$rec['content']);
if (!empty($rec['path'])) {
$objectArray[$count]->path[] = $rec['path'];
}
$count++;
} else {
if (!empty($rec['path'])) {
$objectArray[$key]->path[] = $rec['path'];
}
}
}
return $objectArray;
}
public function insert($main) {
if (!($main instanceof Main)) {
return false;
}
//检查要修改的记录主键是否存在
$where = new Where();
$where->addPredicate(new Operator('name', Operator::OPERATOR_EQUAL_TO, $main->name));
$resultSet = $this->tableGateway->select($where);
if (count($resultSet) > 0) {
return false;
}
try {
$data = $main->getArrayCopy();
//获取要插入assisttable表的内容
$dataAssist = array();
foreach ($data['path'] as $path) {
$dataAssist[] = array('mainName' => $data['name'], 'path' => $path);
}
$insertFeature = new MaintableFeature('assisttable');
$insertFeature->setParamsForInsert($dataAssist);
$this->tableGateway->getFeatureSet()->addFeature($insertFeature);
unset($data['path']);//移除要写入到assisttable的内容
$ret = $this->tableGateway->insert($data);
if ($ret == 1) {
return true;
}
} catch (Exception $ex) {
}
return false;
}
public function delete($main) {
if (!($main instanceof Main)) {
return false;
}
try {
$deleteFeature = new MaintableFeature('assisttable');
$deleteFeature->setParamsForDelete($main->name);
$this->tableGateway->getFeatureSet()->addFeature($deleteFeature);
$ret = $this->tableGateway->delete(array('name' => $main->name));
if ($ret == 1) {
return true;
}
} catch (Exception $ex) {
}
return false;
}
public function update($main) {
if (!($main instanceof Main)) {
return false;
}
//检查要修改的记录主键是否存在
$where = new Where();
$where->addPredicate(new Operator('name', Operator::OPERATOR_EQUAL_TO, $main->name));
$resultSet = $this->tableGateway->select($where);
if (count($resultSet) > 0) {
$data = $main->getArrayCopy();
//获取要插入assisttable表的内容
$dataAssist = array();
foreach ($data['path'] as $path) {
$dataAssist[] = array('mainName' => $data['name'], 'path' => $path);
}
$updateFeature = new MaintableFeature('assisttable');
$updateFeature->setParamsForUpdate($data['name'], $dataAssist);
$this->tableGateway->getFeatureSet()->addFeature($updateFeature);
unset($data['path']);//移除要写入到assisttable的内容
try {
unset($data['name']);//移除主键
$ret = $this->tableGateway->update($data, array('name' => $main->name));
if ($ret == 1 || $ret == 0) {
return true;
}
} catch (Exception $ex) {
}
}
return false;
}
}
MaintableFeature.php内容如下:
namespace Test\Model;
use Zend\Db\TableGateway\Feature\AbstractFeature;
use Zend\Db\Sql\Select;
use Zend\Db\Sql\Insert;
use Zend\Db\Sql\Delete;
use Zend\Db\Adapter\Driver\ResultInterface;
use Zend\Db\Adapter\Driver\StatementInterface;
class MaintableFeature extends AbstractFeature {
protected $assistTable;//assistTable
//select ref
protected $onForSelect;
protected $clumsForSelect;
protected $methodForSelect;
//insert ref
protected $valsForInsert;
//delete ref
protected $mainNameForDelete;
//update ref
protected $valsForUpdate;
protected $mainNameForUpdate;
public function __construct($assistTable) {
$this->assistTable = $assistTable;
}
public function setParamsForSelect($on, $clums=null, $method=null) {
$this->onForSelect = $on;
$this->clumsForSelect = $clums;
$this->methodForSelect = $method;
}
public function preSelect(Select $select) {
$select->join($this->assistTable,
$this->onForSelect,
empty($this->clumsForSelect)?Select::SQL_STAR:$this->clumsForSelect,
empty($this->methodForSelect)?Select::JOIN_LEFT:$this->methodForSelect
);
}
public function setParamsForInsert($valsForInsert) {
$this->valsForInsert = $valsForInsert;
}
public function postInsert(StatementInterface $statement, ResultInterface $result)
{
foreach ($this->valsForInsert as $vals) {
$insert = new Insert($this->assistTable);
$insert->values($vals);
$statement = $this->tableGateway->getAdapter()->getDriver()->createStatement();
$insert->prepareStatement($this->tableGateway->getAdapter(), $statement);
$result = $statement->execute();
}
}
public function setParamsForDelete($mainNameForDelete) {
$this->mainNameForDelete = $mainNameForDelete;
}
public function postDelete(StatementInterface $statement, ResultInterface $result) {
$delete = new Delete($this->assistTable);
$delete->where(array('mainName' => $this->mainNameForDelete));
$statement = $this->tableGateway->getAdapter()->getDriver()->createStatement();
$delete->prepareStatement($this->tableGateway->getAdapter(), $statement);
$result = $statement->execute();
}
public function setParamsForUpdate($mainNameForUpdate, $valsForUpdate) {
$this->mainNameForUpdate = $mainNameForUpdate;
$this->valsForUpdate = $valsForUpdate;
}
public function postUpdate(StatementInterface $statement, ResultInterface $result) {
//delete asssist records first
$delete = new Delete($this->assistTable);
$delete->where(array('mainName' => $this->mainNameForUpdate));
$statement = $this->tableGateway->getAdapter()->getDriver()->createStatement();
$delete->prepareStatement($this->tableGateway->getAdapter(), $statement);
$result = $statement->execute();
//insert assist records next
foreach ($this->valsForUpdate as $vals) {
$insert = new Insert($this->assistTable);
$insert->values($vals);
$statement = $this->tableGateway->getAdapter()->getDriver()->createStatement();
$insert->prepareStatement($this->tableGateway->getAdapter(), $statement);
$result = $statement->execute();
}
}
}
MaintableFeature类主要实现tableGateway在执行select、update、delete和insert操作的时候,对关联表assisttable也执行相应操作。
打开Module\Test\Module.php文件,修改getServiceConfig函数:
public function getServiceConfig()
{
return array(
'factories' => array(
'Test\Model\ATable' => function($sm) {
$tableGateway = $sm->get('ATableGateway');
$table = new ATable($tableGateway);
return $table;
},
'ATableGateway' => function ($sm) {
$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
$resultSetPrototype = new ResultSet();
$resultSetPrototype->setArrayObjectPrototype(new A());
return new TableGateway('a', $dbAdapter, null, $resultSetPrototype);
},
'Test\Model\BTable' => function($sm) {
$tableGateway = $sm->get('BTableGateway');
$table = new BTable($tableGateway);
return $table;
},
'BTableGateway' => function ($sm) {
$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
//指定结果集是array,就可以阻止tableGateway将结果集的记录映射成对象
//这是就需要在BTable的select函数里手动将数组转换为对象
$resultSetPrototype = new ResultSet(ResultSet::TYPE_ARRAY);
return new TableGateway('a', $dbAdapter, null, $resultSetPrototype);
},
'Test\Model\MainTable' => function($sm) {
$tableGateway = $sm->get('MainTableGateway');
$table = new MainTable($tableGateway);
return $table;
},
'MainTableGateway' => function ($sm) {
$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
//由于查询到的结果集无法将assist表的记录集按main表的主键聚合到Main对象内
//因此,此处还是阻止tableGateway将结果集的记录映射成对象
//之后在MainTable的select函数里手动将数组转换为对象
$resultSetPrototype = new ResultSet(ResultSet::TYPE_ARRAY);
return new TableGateway('maintable', $dbAdapter, null, $resultSetPrototype);
},
),
);
}
在Module\Test\src\Test\Controller\TestController.php中添加对象Main的CRUD四个控制器:
class TestController extends AbstractActionController {
protected $mainTable;
public function getMainTable() {
if (!$this->mainTable) {
$sm = $this->getServiceLocator();
$this->mainTable = $sm->get('Test\Model\MainTable');
}
return $this->mainTable;
}
public function selectmainAction() {
$name = $this->params()->fromQuery('name');
if (!empty($name)) {
$where = new Where();
$where->addPredicate(new Operator('name', Operator::OPERATOR_EQUAL_TO, $name));
}
$resultSet = $this->getMainTable()->select((isset($where)?$where:null));
return new ViewModel(array(
'mains' => $resultSet,
));
}
public function insertmainAction() {
$name = $this->params()->fromQuery('name');
if (empty($name)) {
$name = 'main';
}
$main = new Main();
$main->name = $name;
$main->content = "main content";
$main->path[] = 'path1';
$main->path[] = 'path2';
$ret = $this->getMainTable()->insert($main);
return new ViewModel(array(
'ret' => ($ret==false?"false":"true"),
));
}
public function deletemainAction() {
$name = $this->params()->fromQuery('name');
if (empty($name)) {
$name = 'name';
}
$main = new Main();
$main->name = $name;
$ret = $this->getMainTable()->delete($main);
return new ViewModel(array(
'ret' => ($ret==false?"false":"true"),
));
}
public function updatemainAction() {
$name = $this->params()->fromQuery('name');
if (empty($name)) {
$name = 'name';
}
$main = new Main();
$main->name = $name;
$main->content = 'new content';
$main->path = array();
$main->path[] = 'patha';
$ret = $this->getMainTable()->update($main);
return new ViewModel(array(
'ret' => ($ret==false?"false":"true"),
));
}
}
同时记得添加引用:
use Test\Model\Main;
最后在Module\Test\view\test\test\目录下新建selectmain.phtml、insertmain.phtml、updatemain.phtml和deletemain.phtml:
//selectmain.phtml
$title = 'selectMain';
$this->headTitle($title);
?>
<h1><?php echo $this->escapeHtml($title); ?></h1>
<?php
foreach ($this->mains as $main) {
echo $this->escapeHtml($main->name);
echo "------";
echo $this->escapeHtml($main->content);
echo "------";
foreach ($main->path as $path) {
echo $this->escapeHtml($path);
echo "------";
}
echo "<br/>";
}
//insertmain.phtml
$title = 'insertMain';
$this->headTitle($title);
?>
<h1><?php echo $this->escapeHtml($title); ?></h1>
<?php
echo $this->ret;
echo "<br/>";
//updatemain.phtml
$title = 'updateMain';
$this->headTitle($title);
?>
<h1><?php echo $this->escapeHtml($title); ?></h1>
<?php
echo $this->ret;
echo "<br/>";
//deletemain.phtml
$title = 'deleteMain';
$this->headTitle($title);
?>
<h1><?php echo $this->escapeHtml($title); ?></h1>
<?php
echo $this->ret;
echo "<br/>";
读取(Retrieve)使用http://xxxx/test/selectmain或者http://xxx/test/selectmain?name=y。
增加(Create)使用http://xxx/test/insertmain?name=y。
更新(Update)使用http://xxx/test/insertmain?name=y。
删除(Delete)使用http://xxx/test/deletemain?name=y。