Doctrine + Zend Framework 2:在多对多关系中插入数据数组
Doctrine + Zend Framework 2: Insert array of data in a many to many relationship
我有一个使用 Zend Framework2 和 Doctrine2 作为 ORM 的应用程序。
我有一个名为用户的实体:
namespace Adm\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
* @ORM\Table(name="user")
*/
class User{
/**
* @ORM\Id
* @ORM\Column(type="integer");
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @ORM\Column(type="string")
*/
protected $name;
/**
* @ORM\Column(type="string")
*/
protected $email;
/**
* @ORM\Column(type="string")
*/
protected $password;
/**
* @ORM\ManyToMany(targetEntity="Module")
* @ORM\JoinTable(
* name="user_module",
* joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")},
* inverseJoinColumns={@ORM\JoinColumn(name="module_id", referencedColumnName="id")}
* )
*/
protected $modules;
public function __construct() {
$this->modules = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* @return the $id
*/
public function getId() {
return $this->id;
}
/**
* @return the $name
*/
public function getName() {
return $this->name;
}
/**
* @return the $email
*/
public function getEmail() {
return $this->email;
}
/**
* @return the $password
*/
public function getPassword() {
return $this->password;
}
/**
* @param field_type $id
*/
public function setId($id) {
$this->id = $id;
}
/**
* @param field_type $name
*/
public function setName($name) {
$this->name = $name;
}
/**
* @param field_type $email
*/
public function setEmail($email) {
$this->email = $email;
}
/**
* @param field_type $password
*/
public function setPassword($password) {
$this->password = $password;
}
/**
* Add module
*
* @param dm\Entity\Module
* @return User
*/
public function addModules(Module $modules = null){
$this->modules[] = $modules;
}
/**
* Get modules
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getModules(){
return $this->modules;
}
}
查看模块 属性 是一种多对多关系,其中 table 称为 user_modules。
我也有实体模块:
namespace Adm\Entity;
use Doctrine\ORM\Mapping as ORM;
class Module{
/**
* @ORM\Id
* @ORM\Column(type="integer");
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\Column(type="string")
*/
private $name;
/**
* @ORM\Column(type="integer")
*/
private $status;
/**
* @return the $id
*/
public function getId() {
return $this->id;
}
/**
* @return the $name
*/
public function getName() {
return $this->name;
}
/**
* @return the $status
*/
public function getStatus() {
return $this->status;
}
/**
* @param field_type $id
*/
public function setId($id) {
$this->id = $id;
}
/**
* @param field_type $name
*/
public function setName($name) {
$this->name = $name;
}
/**
* @param field_type $status
*/
public function setStatus($status) {
$this->status = $status;
}
}
我收到一个数组变量,其中包含来自表单的 Post 以插入 table。正如预期的那样,每个 post 元素在实体中都有它的 属性 。我有一个 $module 变量,它是一个包含模块 ID 的数组。我的问题是:如何将此数据插入 user_module table?
我的添加功能是这样的:
public function addUser($newUser){
$user = new User();
$user->setName($newUser['name']);
...
$this->getEm()->persist($user);
$this->getEm()->flush();
}
您应该阅读有关使用 cascade
的内容。这将允许您 save/modify/remove 关联关系以及您期望它如何工作。
在这种情况下,您需要与 persist
的关系,因为您希望在保存用户本身时保存关联的实体。
@ORM\ManyToMany(targetEntity="Module", cascade={"persist"})
By default, no operations are cascaded.
存在以下级联选项:
persist : 将操作级联到关联实体。
remove : 级联移除相关实体的操作。
merge : 将合并操作级联到关联实体。
detach : 级联分离操作到关联的实体。
refresh : 将刷新操作级联到关联的实体。
all : 级联对关联实体进行持久化、删除、合并、刷新和分离操作。
首先你需要有@skrilled提到的cascade={"persist"}
。
然后您需要从数据库中检索模块实体。您提到您在 $module 变量中有 id。
你需要这样的 DQL 语句
$builder = $this->getEntityManager()->createQueryBuilder();
$builder->select('m')
->from('Adm\Entity\Module', 'm')
->where('m.id IN (:modules)')
->setParameter('modules', $modules);
$moduleEntities= $builder->getQuery()->getResult(Query::HYDRATE_OBJECT);
并且在您的用户实体中您将需要
public function addModules(Array $moduleEntities)
{
foreach ($moduleEntities as $module) {
if ($module instanceof Module) {
$this->modules[] = $module;
}
}
return $this;
}
最后,在您的 addUser 方法中,您需要添加来自上述 DQL 的模块数组
public function addUser($newUser, $moduleEntities)
{
$user = new User();
$user->setName($newUser['name']);
....
$user->addModules($moduleEntities);
$this->getEm()->persist($user);
$this->getEm()->flush();
}
希望对您有所帮助
我有一个使用 Zend Framework2 和 Doctrine2 作为 ORM 的应用程序。 我有一个名为用户的实体:
namespace Adm\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
* @ORM\Table(name="user")
*/
class User{
/**
* @ORM\Id
* @ORM\Column(type="integer");
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @ORM\Column(type="string")
*/
protected $name;
/**
* @ORM\Column(type="string")
*/
protected $email;
/**
* @ORM\Column(type="string")
*/
protected $password;
/**
* @ORM\ManyToMany(targetEntity="Module")
* @ORM\JoinTable(
* name="user_module",
* joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")},
* inverseJoinColumns={@ORM\JoinColumn(name="module_id", referencedColumnName="id")}
* )
*/
protected $modules;
public function __construct() {
$this->modules = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* @return the $id
*/
public function getId() {
return $this->id;
}
/**
* @return the $name
*/
public function getName() {
return $this->name;
}
/**
* @return the $email
*/
public function getEmail() {
return $this->email;
}
/**
* @return the $password
*/
public function getPassword() {
return $this->password;
}
/**
* @param field_type $id
*/
public function setId($id) {
$this->id = $id;
}
/**
* @param field_type $name
*/
public function setName($name) {
$this->name = $name;
}
/**
* @param field_type $email
*/
public function setEmail($email) {
$this->email = $email;
}
/**
* @param field_type $password
*/
public function setPassword($password) {
$this->password = $password;
}
/**
* Add module
*
* @param dm\Entity\Module
* @return User
*/
public function addModules(Module $modules = null){
$this->modules[] = $modules;
}
/**
* Get modules
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getModules(){
return $this->modules;
}
}
查看模块 属性 是一种多对多关系,其中 table 称为 user_modules。 我也有实体模块:
namespace Adm\Entity;
use Doctrine\ORM\Mapping as ORM;
class Module{
/**
* @ORM\Id
* @ORM\Column(type="integer");
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\Column(type="string")
*/
private $name;
/**
* @ORM\Column(type="integer")
*/
private $status;
/**
* @return the $id
*/
public function getId() {
return $this->id;
}
/**
* @return the $name
*/
public function getName() {
return $this->name;
}
/**
* @return the $status
*/
public function getStatus() {
return $this->status;
}
/**
* @param field_type $id
*/
public function setId($id) {
$this->id = $id;
}
/**
* @param field_type $name
*/
public function setName($name) {
$this->name = $name;
}
/**
* @param field_type $status
*/
public function setStatus($status) {
$this->status = $status;
}
}
我收到一个数组变量,其中包含来自表单的 Post 以插入 table。正如预期的那样,每个 post 元素在实体中都有它的 属性 。我有一个 $module 变量,它是一个包含模块 ID 的数组。我的问题是:如何将此数据插入 user_module table? 我的添加功能是这样的:
public function addUser($newUser){
$user = new User();
$user->setName($newUser['name']);
...
$this->getEm()->persist($user);
$this->getEm()->flush();
}
您应该阅读有关使用 cascade
的内容。这将允许您 save/modify/remove 关联关系以及您期望它如何工作。
在这种情况下,您需要与 persist
的关系,因为您希望在保存用户本身时保存关联的实体。
@ORM\ManyToMany(targetEntity="Module", cascade={"persist"})
By default, no operations are cascaded.
存在以下级联选项:
persist : 将操作级联到关联实体。
remove : 级联移除相关实体的操作。
merge : 将合并操作级联到关联实体。
detach : 级联分离操作到关联的实体。
refresh : 将刷新操作级联到关联的实体。
all : 级联对关联实体进行持久化、删除、合并、刷新和分离操作。
首先你需要有@skrilled提到的cascade={"persist"}
。
然后您需要从数据库中检索模块实体。您提到您在 $module 变量中有 id。
你需要这样的 DQL 语句
$builder = $this->getEntityManager()->createQueryBuilder();
$builder->select('m')
->from('Adm\Entity\Module', 'm')
->where('m.id IN (:modules)')
->setParameter('modules', $modules);
$moduleEntities= $builder->getQuery()->getResult(Query::HYDRATE_OBJECT);
并且在您的用户实体中您将需要
public function addModules(Array $moduleEntities)
{
foreach ($moduleEntities as $module) {
if ($module instanceof Module) {
$this->modules[] = $module;
}
}
return $this;
}
最后,在您的 addUser 方法中,您需要添加来自上述 DQL 的模块数组
public function addUser($newUser, $moduleEntities)
{
$user = new User();
$user->setName($newUser['name']);
....
$user->addModules($moduleEntities);
$this->getEm()->persist($user);
$this->getEm()->flush();
}
希望对您有所帮助