【发布时间】:2019-04-26 03:21:38
【问题描述】:
由于历史原因,我使用 Symfony 运行数据库的模式是混合的。也就是说,查询使用 DBAL,插入使用 ORM。现在您需要将大量数据写入数据库。 ORM中的flush可以帮助我以最低的成本实现业务。
所有flush 操作已从项目中删除。把它放在controller 的__destruct 中。
但是,这样做会导致 DBAL 找不到最新更改的数据。当然,这些数据ORMs是可以正常获取的。
这是一个非常困难的问题。希望得到指导。
class BaseController extends Controller
{
public function __destruct()
{
$this->getDoctrine()->getManager()->flush();
}
public function indexAction()
{
$model = new CompanyModel();
$model->install(['company_name' => '1234']);
$model->update(['company_name' => 'abcd'], $model->lastInsertId);
}
}
class CompanyModel extends BaseController
{
public function validate($data, $id = false)
{
$this->entityManager = $this->getDoctrine()->getManager();
if(empty($id)){
$this->company_class = new Company();
}else{
if(!$this->is_exist($id)){
return false;
}
$this->company_class = $this->entityManager->getRepository(Company::class)->find($id);
}
if(array_key_exists('company_name', $data)){
$this->company_class->setCompanyName($data['company_name']);
}
if(self::$error->validate($this->company_class)){
return false;
}
return true;
}
public function insert($data)
{
if(!$this->validate($data)){
return false;
}
$this->company_class->setCreateAt(new \DateTime());
$this->entityManager->persist($this->company_class);
//$this->entityManager->flush();
$this->lastInsertId = $this->company_class->getId();
return true;
}
public function update($data, $id)
{
if(empty($id)){
self::$error->setError('param id is not null');
return false;
}
if(!$this->validate($data, $id)){
return false;
}
$this->company_class->setUpdateAt(new \DateTime());
//$this->entityManager->flush();
return true;
}
public function is_exist($id)
{
return $this->get('database_connection')->fetchColumn('...');
}
}
执行indexActioncompany_name的最终结果是1234; $ model-> update() 未成功执行。原因是接受DBAL查询的$this-> is_exist()方法没有找到ORM插入但是没有flush消息。
条件不变,运行
$this->entityManager->getRepository(Company::class)->find($id);
成功了。
【问题讨论】:
-
为了将flush方法放入__destruct()中。它对你有用吗?
-
您可以尝试
beginTransaction/commit将其全部包装在事务中,并在更改后立即刷新。这可能会稍微提高性能。然而,看起来你的模式很糟糕,你不应该混合。 ORM 就像一个临时区域,如果您工作正常,则不需要 id 即可使其在 orm 中工作。将其与 dbal 混合是一个问题,可能会在某些时候导致不一致和代码异味,应尽快重构。 (我会给出建议,但您提供的代码示例太少,无法显示 dbal 导致问题的位置) -
@Jakumi 非常感谢你。我完善了我的问题。
-
@MiteshVasava 非常感谢。我完善了我的问题。
标签: php symfony orm doctrine dbal