Symfony2,Doctrine2更新没有ID的行(此表只有“一行”)

时间:2013-10-07 14:03:14

标签: php symfony doctrine-orm

我想创建我的实体设置,其中包含有关我的网页的基本可编辑信息。我用这个来源创建了我的实体 Settings.php

<?php
namespace Acme\SettingsBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity()
 * @ORM\Table(name="settings") 
 */ 
class Settings
{    
    /**
     * @ORM\Column(type="string", length=100)
     */ 
    protected $page_name;

    /**
     * @ORM\Column(type="string", length=100)
     */
    protected $page_description;

    /**
     * @ORM\Column(type="string", length=100)
     */
    protected $page_email;                  
}

我不知道,如何告诉我的控制器只会覆盖现有数据,而不是创建新数据。这是我的控制器 AdminController.php

public function indexAction(Request $request)
{
    if (false === $this->get('security.context')->isGranted('ROLE_ADMIN')) {
        throw new AccessDeniedException();
    }

    $settings = new Settings();

    $form = $this->createForm('settings', $settings);
    $form->handleRequest($request); 

    if($form->isValid())
    {
        $em = $this->getDoctrine()->getManager();
        $em->persist($settings);

        try {
            $em->flush();
        } catch (\PDOException $e) {
            // sth
        }
        $this->get('session')->getFlashBag()->add(
            'success',
            'Settings was successfuly changed'
        );
    }

    return $this->render('AcmeSettingsBundle:Admin:index.html.twig', array('form' => $form));
}

我没有测试它,但我相信,它会使用新数据创建一个新的Settings对象。有什么帮助吗?

1 个答案:

答案 0 :(得分:1)

你应该总是设置一些字段作为ID,即使它是虚拟的。

指定一些您将始终使用的默认值,然后您应该能够毫无问题地更新您的设置。

通常,DBMS会向您展示缺少唯一标识符,因此同样适用于Doctrine。

$settings = new Settings();
$settings->setId(Settings::DUMMY_IDENTIFIER); // const within class

# rest of the logic
# ....
$em = $this->getDoctrine()->getManager();
$em->persist($settings);

try {
    $em->flush();
} catch (\PDOException $e) {
}

您可以采取另一种方法:将每个属性保留为单行。但是,您需要构建更复杂的表单类型并执行更多查询。

修改

您可以使用原始SQL,但灵活性较低:

# raw query
$sql = "UPDATE settings SET page_name = ?, page_description = ?, page_email = ?";

# data
$params = array( $settings->getPageName(), $settings->getPageDesc(), $settings->getPageEmail());

# must specify type due to protection against sql injection
$types = array(\PDO::PARAM_STR,\PDO::PARAM_STR,\PDO::PARAM_STR);

# execute it
$stmt = $this->getEntityManager()->getConnection()->executeUpdate($sql, $params, $types);

http://docs.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/data-retrieval-and-manipulation.html#using-prepared-statements