ZF2 - Doctrine ORM,简单表连接
Posted
技术标签:
【中文标题】ZF2 - Doctrine ORM,简单表连接【英文标题】:ZF2 - Doctrine ORM, Simple Table Join 【发布时间】:2014-05-05 08:40:34 【问题描述】:我目前正在学习如何将 Doctrine ORM 与 ZF2 一起使用,目前我的目标是从简单的表连接中检索数据并将其显示到屏幕上。
我已经阅读了文档,看起来很简单。
这些是我的桌子:
user
------------------------
|user_id | name | email |
--------------------------
| 1 | John | j@b.com |
--------------------------
| 2 | Bob | b@j.com |
--------------------------
user_role_linker
--------------------------
|user_id | role_id |
--------------------------
| 1 | administrator |
--------------------------
| 2 | staff |
--------------------------
我想要实现的是我的观点列表如下:
ID Name Email Role Actions
--------------------------------------------------------
1 John j@b.com Administrator Edit
2 Bob b@j.com Staff Edit
--------------------------------------------------------
Paging goes here
----------------
这是我目前拥有的,它似乎可以工作,除了我不确定如何获取连接的表数据:
User entity::
<?php
namespace Administration\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\ORM\Mapping\ManyToMany;
use Doctrine\ORM\Mapping\JoinTable;
use Doctrine\ORM\Mapping\JoinColumn;
use Doctrine\Common\Collections\ArrayCollection;
/** @ORM\Entity */
class User
/**
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
* @ORM\Column(type="integer",name="user_id")
*/
protected $user_id;
/** @ORM\Column(type="integer", name="parent_id") */
protected $parent_id;
/** @ORM\Column(type="string", name="name") */
protected $name;
/** @ORM\Column(type="string", name="email") */
protected $email;
//Setters and getters
public function getUserId()
return $this->user_id;
public function setName($name)
$this->name = $name;
public function getName()
return $this->name;
public function getEmail()
return $this->email;
public function setEmail($email)
$this->email = $email;
/**
* @ManyToMany(targetEntity="UserRoleLinker")
* @JoinTable(
* name="user_role_linker",
* joinColumns=
* @JoinColumn(
* name="user_id",
* referencedColumnName="id")
* ,
* inverseJoinColumns=
* @JoinColumn(
* name="user_id",
* referencedColumnName="id",
* unique=true)
* )
*/
private $role_id;
public function __construct()
$this->role_id = new ArrayCollection();
/** @return Collection */
public function getRoleId()
return $this->role_id;
用户角色链接器实体::
<?php
namespace Administration\Entity;
use Doctrine\ORM\Mapping as ORM;
/** @ORM\Entity */
class UserRoleLinker
/**
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
* @ORM\Column(type="integer",name="user_id")
*/
protected $user_id;
/** @ORM\Column(type="string", name="role_id") */
protected $role_id;
/** @param User|null */
public function getRoleId()
return $this->role_id;
我的管理控制器::
public function usersAction()
$em = $this->getServiceLocator()->get('Doctrine\ORM\EntityManager');
$userFunctions = new UserFunction($em);
$userArray = $userFunctions->getUsers();
$viewModel = new ViewModel(array('users' => $userArray));
return $viewModel;
这调用了我的 UserFunctions 类::
public function getUsers()
//This function returns the users
return $this->em->getRepository('Administration\Entity\User')->findAll();
在我看来,我列出的数据如下:
<?php
foreach ($this->users AS $user)
?>
<tbody>
<tr class="odd gradeX">
<td ><?php echo $user->getUserId(); ?></td>
<td><?php echo $user->getName(); ?></td>
<td><?php echo $user->getEmail(); ?></td>
<td class="center">*** HOW DO I SHOW THE ROLE ?? ***</td>
<td>Edit</td>
</tr>
<?php ?>
如何获取要在视图中显示的角色?
【问题讨论】:
在这里查看关联映射:docs.doctrine-project.org/en/2.0.x/reference/… 【参考方案1】:您必须在实体定义中定义用户和角色之间的正确关系。
我不确定你为什么在这里使用链接器表。您是否真的想在用户和角色之间建立多对多关系(每个用户都可以有多个角色?)。
如果不是,您可以轻松地将角色 ID 移动到用户表中,然后在用户和角色之间定义 ManyToOne
关系。
您的用户表将如下所示:
-------------------------------------------
|user_id | name | email | role_id |
-------------------------------------------
| 1 | John | j@b.com | administrator |
-------------------------------------------
| 2 | Bob | b@j.com | staff |
-------------------------------------------
我建议以用户为拥有方查看ManyToOne
。您可以在the Doctrine2 documentationthe Doctrine2 documentation
之后,您可以在视图中简单地调用$user->getRole();
...
编辑
使用连接表修复一对多的答案:
这在doctrine documentation here...中也有描述
你需要三张桌子;一个用户表、一个角色表和一个用户角色链接器表 用户是实体,角色是实体,角色链接器表在您的情况下不是实体。您应该删除该实体,链接器表仅用于连接数据库中的用户和角色。
用户表
---------------------------
|id | name | email |
---------------------------
| 1 | John | j@b.com |
---------------------------
| 2 | Bob | b@j.com |
---------------------------
角色表
-----------------
| id |
-----------------
| administrator |
-----------------
| staff |
-----------------
| guest |
-----------------
| another role |
-----------------
链接器表
--------------------------
|user_id | role_id |
--------------------------
| 1 | administrator |
--------------------------
| 2 | staff |
--------------------------
在您的用户实体中:
/** ONE-TO-MANY UNIDIRECTIONAL, WITH JOIN TABLE ONLY WORK WITH MANY-TO-MANY ANNOTATION AND A UNIQUE CONSTRAINT
* @ORM\ManyToMany(targetEntity="Administration\Entity\Role")
* @ORM\JoinTable(name="user_role_linker",
* joinColumns=@ORM\JoinColumn(name="user_id", referencedColumnName="id"),
* inverseJoinColumns=@ORM\JoinColumn(name="role_id", referencedColumnName="id", unique=true)
* )
*/
protected $roles;
/**
* Get roles.
*
* @return ArrayCollection
*/
public function getRoles()
return $this->roles;
/**
* Add a role to the user.
*
* @param Role $role
*
* @return User
*/
public function addRole(Role $role)
$this->roles[] = $role;
return $this;
/**
* Remove a role from the user
*
* @param Role $role
*
* @return User
*/
public function removeRole(Role $role)
$this->roles->removeElement($role);
return $this;
你的角色实体:
/**
* An example entity that represents a role.
*
* @ORM\Entity
* @ORM\Table(name="role")
* @property string $id
*/
class Role
/**
* @var string
* @ORM\Id
* @ORM\Column(type="string", length=255, unique=true, nullable=false)
*/
protected $id;
/**
* Get the id.
*
* @return string
*/
public function getId()
return $this->id;
我认为这应该可以帮助您解决它...
也许您应该将以下内容添加到您的应用程序模块中:
public function doctrineValidate(MvcEvent $event)
$application = $event->getParam('application');
$serviceManager = $application->getServiceManager();
$entityManager = $serviceManager->get('doctrine.entitymanager.orm_default');
$validator = new SchemaValidator($entityManager);
$errors = $validator->validateMapping();
if (count($errors) > 0)
// Lots of errors!
var_dump($errors);
然后在引导中:
$eventManager->attach('dispatch', array($this, 'doctrineValidate'));
在模块中: Doctrine 将通过检查您的实体定义来帮助您。它可能会提前告诉您实体定义中有问题...
【讨论】:
【参考方案2】:这令人困惑,但正如您在实体中定义的那样,您可以使用 User 实体 getRoleId 的函数获取角色集合。然后,对于每个 UserRoleLinker 实体,您必须再次使用 getRoleId 函数,该函数将返回“Administrator”或“Staff”字符串。循环示例:
$roles = $user->getRoleId();
foreach ( $roles as $role )
$roleId = $role->getRoleId();
我建议你换一种方式。一个实体应该是User,具有一个名为roles 的属性。另一方面,您可以拥有实体 Role。它们之间的链接应该是One-To-Many, Unidirectional with Join Table(即 user_role_linker 表)。
【讨论】:
我已尝试使用您的建议使其正常工作,请查看我添加的答案...收到一些不寻常的通知,对象也没有获得所需的信息。【参考方案3】:正如 lluisaznar 所建议的(虽然我需要多对一的关系,因为每个用户只有一个角色)。
我正在尝试以下方法:
<?php
namespace Administration\Entity;
//use stuff
/** @ORM\Entity */
class User
/**
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
* @ORM\Column(type="integer",name="user_id")
*/
//setters getters
/**
* @ManyToOne(targetEntity="Role")
* @JoinColumn(name="user_id", referencedColumnName="id")
*/
private $role;
public function __construct()
$this->role = new ArrayCollection();
/** @return Collection */
public function getRoleId()
return $this->role;
以及角色实体:
<?php
namespace Administration\Entity;
use Doctrine\ORM\Mapping as ORM;
/** @ORM\Entity */
class Role
/**
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
* @ORM\Column(type="integer",name="user_id")
*/
protected $user_id;
/** @ORM\Column(type="string", name="role_id") */
protected $role;
/** @param User|null */
public function getRoleId()
return $this->role;
当我运行它时,我会收到以下通知:
Notice: Undefined index: id in trunk/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php on line 2611
和
Notice: Undefined index: user_id in trunk/vendor/doctrine/common/lib/Doctrine/Common/Proxy/AbstractProxyFactory.php on line 121
角色也没有被显示,当我将 $user 对象转储到角色下时,我得到了这个:
private 'role' =>
object(DoctrineORMModule\Proxy\__CG__\Administration\Entity\Role)[609]
public '__initializer__' =>
object(Closure)[595]
public '__cloner__' =>
object(Closure)[596]
public '__isInitialized__' => boolean false
protected 'user_id' => null
protected 'role' => null
【讨论】:
如果您有ManyToOne
关系,则不需要链接器表。删除链接器表并将role_id
列添加到您的用户表。查看我的答案了解更多详情。
是的 - 这是我通常会做的事情。不幸的是,链接器表是 BjyAuthorize / ZFCUser 的一部分,并且每次更新第三方模块时都无法在不请求麻烦的情况下将其删除。通常我会做一个简单的 sql 连接,而不会三思而后行……似乎 ORM 中的一个简单连接需要火箭科学的 PHD! :)
没有一个简单的连接只是一个简单的连接:) 如果我今天晚些时候有时间我会看看你的代码并帮助你。现在问题出在哪里?还是同样的问题?
谢谢威尔特,将不胜感激。我可以通过标准实体访问数据库。我苦苦挣扎的地方是如何连接两个表(例如上面的)并将所需的信息返回到视图。理想情况下,我想在其中添加分页,但是我认为在考虑分页之前我需要先了解连接。
成功了吗?以上是关于ZF2 - Doctrine ORM,简单表连接的主要内容,如果未能解决你的问题,请参考以下文章
ZF2 Skeleton 和 Doctrine ORM xml 模式合并
Zend/Doctrine 不能执行 ORM 操作,表已经存在