Symfony2 中使用 Doctrine 注释的多个 JoinColumns? [英] Multiple JoinColumns in Symfony2 using Doctrine annotations?

查看:21
本文介绍了Symfony2 中使用 Doctrine 注释的多个 JoinColumns?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问题来了:

Class Routing 具有属性 objectIdobjectType.objectId 是一个整数,objectType 是一个字符串.这样做的原因是允许同一个表保存不同类型路由的数据.例如对于ProductsDepartmentBrand 的路由.所以,objectTypeobjectId 的组合就是我的 JoinColumn.

如何与 Doctrine2 建立这种双向关系?我查看了继承关系,但似乎没有一个概念是我正在寻找的.

我可以在数据库中创建一些视图,并且只有几个不同的路由实体,但这似乎不是最好的路由.

这是我的实体 DepartmentProductBrand.

../Entity/Department.php

使用 Doctrine\ORM\Mapping 作为 ORM;/*** @ORM\Entity()* @ORM\Table(name="部门")*/类 Department 实现了 DescribableInterface{/*** @ORM\Id* @ORM\Column(name="id", type="integer", length=11)* @ORM\GeneratedValue(strategy="AUTO")*/私人 $id;/*** @ORM\Column(name="status", type="string", length=1)*/私人 $status;/*** @ORM\Column(name="name", type="string", length=255)*/私人 $name;...

../Entity/Product.php

使用 Doctrine\ORM\Mapping 作为 ORM;/*** @ORM\实体* @ORM\Table(name="products")*/类 Product 实现了 DescribableInterface{/*** @ORM\Id* @ORM\Column(name="id", type="integer", length=11)* @ORM\GeneratedValue(strategy="AUTO")*/私人 $id;/*** @ORM\Column(name="status", type="string", length=1)*/私人 $status;/*** @ORM\Column(name="product_code", type="string", length=100, nullable=true)*/私人 $productCode = '';/*** @ORM\Column(name="name", type="string", length=255)*/私人 $name;...

../Entity/Brand.php

使用 Doctrine\ORM\Mapping 作为 ORM;/*** @ORM\实体* @ORM\Table(name="brands")*/班级品牌{/*** @ORM\Id* @ORM\Column(name="id", type="integer", length=11)* @ORM\GeneratedValue(strategy="AUTO")*/私人 $id;/*** @ORM\Column(name="status", type="string", length=1)*/私人 $status = 'a';/*** @ORM\Column(name="name", type="string", length=255)*/私人 $name;...

每个产品、品牌和部门都有自己的 URL,该 URL 保存在由 object_typeobject_id 设置的路由表中,其中 object_type只是departmentproductbrand 并且object_id 是相应产品、品牌或部门的唯一ID.

../Entity/Routing.php

使用 Doctrine\ORM\Mapping 作为 ORM;/*** @ORM\实体* @ORM\Table(name="路由")*/类路由{/*** @ORM\Id* @ORM\Column(name="id", type="integer", length=11)* @ORM\GeneratedValue(strategy="AUTO")*/私人 $id;/*** @ORM\Column(name="object_id", type="integer", length=11)*/私人 $objectId;/*** @ORM\Column(name="object_type", type="string", length=100)*/私人 $objectType;/*** @ORM\Column(name="url", type="text")*/私人 $url;...

我真正苦恼的是如何建立关系,以便部门、产品和品牌可以从单个路由实体访问其 URL.

我尝试将关系添加到 $objectId,但它似乎不喜欢那样.可以这样设置吗?

我基本上想要实现的是获取数据对象并有能力获取对象的URL,例如:

$departments = $em->getRepository("AdamStaceySiteBundle:Department")->findAll();foreach ($departments 作为 $department){echo '<a href="'.$department->getUrl().'">'.$department->getMenuTitle().'</a>;}

有人可以帮忙吗?

解决方案

经过进一步研究后,我发现一位知情人士 (Dirk Olbertz) 遇到了同样的问题.

信息可在以下位置找到:Google 网上论坛:多个 JoinColumns?

我现在已经实现了这个,我将解释我是如何做到的,因为它可能会帮助其他人.

我的问题的答案是使用单表继承.

我需要做的第一件事是更新 routing 实体以使用单表继承:

../Entity/Routing.php

/*** @ORM\实体* @ORM\InheritanceType("SINGLE_TABLE")* @ORM\DiscriminatorColumn(name="object_type", type="string")* @ORM\DiscriminatorMap({"product" = "ProductRouting", "department" = "DepartmentRouting", "brand" = "BrandRouting"})* @ORM\Table(name="路由")*/类路由{/*** @ORM\Id* @ORM\Column(name="id", type="integer", length=11)* @ORM\GeneratedValue(strategy="AUTO")*/私人 $id;...

DiscriminatorColumn 允许我指定将用于链接的列,在本例中是 object_type 字段.

DiscriminatorMap 允许我指定什么 object_type 将与什么实体链接.

然后必须创建这些实体来扩展 Routing 实体.

../Entity/ProductRouting.php

/*** @ORM\实体*/类 ProductRouting 扩展了路由{/*** @ORM\ManyToOne(targetEntity="Product")* @ORM\JoinColumn(name="object_id", referencedColumnName="id")*/受保护的 $product;...

../Entity/DepartmentRouting.php

/*** @ORM\实体*/类 DepartmentRouting 扩展了路由{/*** @ORM\ManyToOne(targetEntity="部门")* @ORM\JoinColumn(name="object_id", referencedColumnName="id")*/受保护的$部门;...

../Entity/BrandRouting.php

/*** @ORM\实体*/BrandRouting 类扩展了路由{/*** @ORM\ManyToOne(targetEntity="品牌")* @ORM\JoinColumn(name="object_id", referencedColumnName="id")*/受保护的 $brand;...

然后在每个 ProductDepartmentBrand 实体中,我需要添加新的 $routings.

../Entity/Product.php

<代码>...产品类别{.../*** @ORM\OneToMany(targetEntity="ProductRouting",mappedBy="product",cascade={"all"})*/私人$路由;...

../Entity/Department.php

<代码>...班级部{.../*** @ORM\OneToMany(targetEntity="DepartmentRouting",mappedBy="department",cascade={"all"})*/私人$路由;...

../Entity/Brand.php

<代码>...班级品牌{.../*** @ORM\OneToMany(targetEntity="BrandRouting",mappedBy="brand",cascade={"all"})*/私人$路由;...

希望有帮助...

Here is the problem:

Class Routing with attributes objectId and objectType. objectId is an int, and objectType is a string. The reason for this was to allow the same table to hold data for different kind of routings. For instance for the routing of Products, Department and Brand. So, the combination of the objectType and the objectId is my JoinColumn.

How do I create such a bidirectional relationship with Doctrine2? I looked at inherited relationships, but none of the concepts seemed to be what I'm looking for.

I could create some views in the database and just have a couple of different Routing entities, but this does not seem the best route.

Here are my entities Department, Product and Brand.

../Entity/Department.php

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity()
 * @ORM\Table(name="departments")
 */
class Department implements DescribableInterface
{
    /**
     * @ORM\Id
     * @ORM\Column(name="id", type="integer", length=11)
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @ORM\Column(name="status", type="string", length=1)
     */
    private $status;

    /**
     * @ORM\Column(name="name", type="string", length=255)
     */
    private $name;
...

../Entity/Product.php

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 * @ORM\Table(name="products")
 */
class Product implements DescribableInterface
{
    /**
     * @ORM\Id
     * @ORM\Column(name="id", type="integer", length=11)
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @ORM\Column(name="status", type="string", length=1)
     */
    private $status;

    /**
     * @ORM\Column(name="product_code", type="string", length=100, nullable=true)
     */
    private $productCode = '';

    /**
     * @ORM\Column(name="name", type="string", length=255)
     */
    private $name;
...

../Entity/Brand.php

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 * @ORM\Table(name="brands")
 */
class Brand
{
    /**
     * @ORM\Id
     * @ORM\Column(name="id", type="integer", length=11)
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @ORM\Column(name="status", type="string", length=1)
     */
    private $status = 'a';

    /**
     * @ORM\Column(name="name", type="string", length=255)
     */
    private $name;
...

Each product, brand and department has its own URL that is held in the routing table set by the object_type and object_id where the object_type is simply department, product or brand and the object_id is the unique id of the corresponding product, brand or department.

../Entity/Routing.php

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 * @ORM\Table(name="routing")
 */
class Routing
{
    /**
     * @ORM\Id
     * @ORM\Column(name="id", type="integer", length=11)
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;    

    /**
     * @ORM\Column(name="object_id", type="integer", length=11)
     */
    private $objectId;

    /**
     * @ORM\Column(name="object_type", type="string", length=100)
     */
    private $objectType;

    /**
     * @ORM\Column(name="url", type="text")
     */
    private $url;
...

What I am really struggling with is how do I setup the relationship, so the departments, products and brands can access their URL from the single routing entity.

I have tried adding the relationships to the $objectId, but it doesn't seem to like that. Is it possible to set this up like this?

What I am basically trying to achieve is to get the data object and have the ability to get the URL of an object, for example:

$departments = $em->getRepository("AdamStaceySiteBundle:Department")->findAll();
foreach ($departments as $department)
{
   echo '<a href="'.$department->getUrl().'">'.$department->getMenuTitle().'</a>;
}

Can anyone help?

解决方案

After further researching I found a man (Dirk Olbertz) in the know who had the same problem.

Information can be found at: Google Groups: Multiple JoinColumns?

I have now implemented this and I will explain how I did it incase it might help anyone else.

The answer to my problem was the use of single table inheritance.

The first thing I needed to do was update the routing entity to use single table inheritance:

../Entity/Routing.php

/**
 * @ORM\Entity
 * @ORM\InheritanceType("SINGLE_TABLE")
 * @ORM\DiscriminatorColumn(name="object_type", type="string")
 * @ORM\DiscriminatorMap({"product" = "ProductRouting", "department" = "DepartmentRouting", "brand" = "BrandRouting"})
 * @ORM\Table(name="routing")
 */
class Routing
{
    /**
     * @ORM\Id
     * @ORM\Column(name="id", type="integer", length=11)
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;
...

The DiscriminatorColumn allowed me to specify what column would be used to link, which in this case was the object_type field.

The DiscriminatorMap allowed me to specify what object_type will link with what entities.

These entities then had to be created that extended the Routing entity.

../Entity/ProductRouting.php

/**
 * @ORM\Entity
 */
class ProductRouting extends Routing
{
    /**
     * @ORM\ManyToOne(targetEntity="Product")
     * @ORM\JoinColumn(name="object_id", referencedColumnName="id")
     */
    protected $product;
...

../Entity/DepartmentRouting.php

/**
 * @ORM\Entity
 */
class DepartmentRouting extends Routing
{
    /**
     * @ORM\ManyToOne(targetEntity="Department")
     * @ORM\JoinColumn(name="object_id", referencedColumnName="id")
     */
    protected $department;
...

../Entity/BrandRouting.php

/**
 * @ORM\Entity
 */
class BrandRouting extends Routing
{
    /**
     * @ORM\ManyToOne(targetEntity="Brand")
     * @ORM\JoinColumn(name="object_id", referencedColumnName="id")
     */
    protected $brand;
...

Then in each of the Product, Department and Brand entities I needed to add the new $routings.

../Entity/Product.php

...
class Product
{
    ...
    /**
     * @ORM\OneToMany(targetEntity="ProductRouting", mappedBy="product", cascade={"all"})
     */
    private $routings;
...

../Entity/Department.php

...
class Department
{
    ...
    /**
     * @ORM\OneToMany(targetEntity="DepartmentRouting", mappedBy="department", cascade={"all"})
     */
    private $routings;
...

../Entity/Brand.php

...
class Brand
{
    ...
    /**
     * @ORM\OneToMany(targetEntity="BrandRouting", mappedBy="brand", cascade={"all"})
     */
    private $routings;
...

Hope that helps...

这篇关于Symfony2 中使用 Doctrine 注释的多个 JoinColumns?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆