我想使用ZF2 db transaction来更新多个表。 通常情况下,我会通过类似的方式对单个表进行交易:
$connection = null;
try {
$connection = $this->tableGateway->getAdapter()->getDriver()->getConnection();
$connection->beginTransaction();
$this->tableGateway->insert($data);
$connection->commit();
}
catch (Exception $e) {
if ($connection instanceof \Zend\Db\Adapter\Driver\ConnectionInterface) {
$connection->rollback();
}
}
现在我想在一个事务中更新两个表。在ZF1中,我通过创建table2类的实例并在同一事务中调用其适当的方法来完成此操作。但由于我不知道在模型中调用另一个模型类的方法,我不能像ZF1那样做。我需要这个用于简单的任务,例如在输入新账单(发票)时向tbl_invoice添加新行并更新tbl_runno表的发票运行编号。
答案 0 :(得分:3)
在您的控制器中,您可以:
$db = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
$con = $db->getDriver()->getConnection();
$con->beginTransaction();
try {
//get tables and do sth
$con->commit();
} catch (Exception $e) {
$con->rollback();
}
答案 1 :(得分:0)
使用DataMapper设计模式。 Pattern TableGateway用于将数据投影到单个表。
https://leanpub.com/zendframework2-en 你可以使用这样的东西:
namespace ScContent\Mapper;
use Zend\Db\Sql\Sql;
use Zend\Db\Sql\Select;
use Zend\Db\Sql\SqlInterface;
use Zend\Db\Sql\PreparableSqlInterface;
use Zend\Db\Adapter\AdapterInterface;
use Zend\Db\Adapter\Driver\ResultInterface;
use Zend\Stdlib\Hydrator\ClassMethods;
use Zend\StdLib\Hydrator\HydratorInterface;
abstract class AbstractDbMapper
{
/**
* @var string
*/
const JoinInner = Select::JOIN_INNER;
/**
* @var string
*/
const JoinLeft = Select::JOIN_LEFT;
/**
* @var string
*/
const JoinRight = Select::JOIN_RIGHT;
/**
* @var Zend\Db\Adapter\AdapterInterface
*/
protected $_adapter;
/**
* @var Zend\Db\Sql\SqlInterface
*/
protected $_sql;
/**
* @var Zend\Stdlib\HydratorInterface
*/
protected $_hydrator;
/**
* @var array
*/
protected $_tables = array();
/**
* @param Zend\Db\Adapter\AdapterInterface $adapter
*/
public function setAdapter(AdapterInterface $adapter)
{
$this->_adapter = $adapter;
}
/**
* @return Zend\Db\Adapter\AdapterInterface
*/
public function getAdapter()
{
if(!$this->_adapter instanceof AdapterInterface) {
throw new Exception('Adapter is not installed.');
}
return $this->_adapter;
}
/**
* @param Zend\Db\Sql\SqlInterface $sql
*/
public function setSql(SqlInterface $sql)
{
$this->_sql = $sql;
}
/**
* @return Zend\Db\Sql\SqlInterface
*/
public function getSql()
{
if(!$this->_sql instanceof SqlInterface) {
$this->_sql = new Sql($this->getAdapter());
}
return $this->_sql;
}
/**
* @param Zend\Stdlib\HydratorInterface $hydrator
*/
public function setHydrator(HydratorInterface $hydrator)
{
$this->_hydrator = $hydrator;
}
/**
* @return Zend\Stdlib\HydratorInterface
*/
public function getHydrator()
{
if(!$this->_hydrator instanceof HydratorInterface) {
$this->_hydrator = new ClassMethods();
}
return $this->_hydrator;
}
/**
* @param string $alias
* @param string $name
*/
public function setTable($alias, $name)
{
$this->_tables[$alias] = $name;
}
/**
* @param string $alias
* @throws Exception
* @return string
*/
public function getTable($alias)
{
if(!array_key_exists($alias, $this->_tables)) {
throw new Exception(sprintf("Unknown table alias '%s'.", $alias));
}
return $this->_tables[$alias];
}
/**
* @return int|null|false
*/
protected function lastInsertId()
{
return $this->adapter->getDriver()->getConnection()->getLastGeneratedValue();
}
/**
* @param void
* @return void
*/
protected function beginTransaction()
{
$this->getAdapter()->getDriver()->getConnection()->beginTransaction();
}
/**
* @param void
* @return void
*/
protected function commit()
{
$this->getAdapter()->getDriver()->getConnection()->commit();
}
/**
* @return bool
*/
protected function inTransaction()
{
return $this->getAdapter()->getDriver()
->getConnection()->getResource()->inTransaction();
}
/**
* @param void
* @return void
*/
protected function rollBack()
{
$this->getAdapter()->getDriver()->getConnection()->rollBack();
}
/**
* @param Zend\Db\Sql\PreparableSqlInterface $sqlObject
* @return Zend\Db\Adapter\ResultInterface
*/
protected function execute(PreparableSqlInterface $sqlObject)
{
return $this->getSql()->prepareStatementForSqlObject($sqlObject)->execute();
}
/**
* @param Zend\Db\Adapter\ResultInterface $source
* @return array
*/
protected function toArray(ResultInterface $source)
{
$result = array();
foreach($source as $item) {
$result[] = $item;
}
return $result;
}
/**
*
*/
protected function toString(SqlInterface $sqlObject)
{
return $this->getSql()->getSqlStringForSqlObject($sqlObject);
}
}
使用示例:
<?php
namespace ScContent\Mapper;
use Zend\Db\Adapter\AdapterInterface;
class ContentMapper extends AbstractDbMapper
{
/**
* @var string
*/
const ContentTableAlias = 'contentalias';
/**
* @var string
*/
const UsersTableAlias = 'usersalias';
/**
* @param AdapterInterface $adapter
*/
public function __construct(AdapterInterface $adapter) {
$this->setAdapter($adapter);
}
/**
* @var array
*/
protected $_tables = array(
self::ContentTableAlias => 'sc_content',
self::UsersTableAlias => 'sc_users'
);
/**
* @param integer $id
* @return null | array
*/
public function findById($id)
{
$select = $this->getSql()->select()
->from(array('content' => $this->getTable(self::ContentTableAlias)))
->join(
array('users' => $this->getTable(self::UsersTableAlias)),
'content.author = users.user_id',
array('username'),
self::JoinInner
)
->where(array('`content`.`id` = ?' => $id));
return $this->execute($select)->current();
}
}