首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Symfony \ Doctrine需要帮助-插入多个表

Symfony \ Doctrine需要帮助-插入多个表
EN

Stack Overflow用户
提问于 2014-01-18 10:43:43
回答 2查看 1.5K关注 0票数 0

我有三张桌子:

  1. 产品- product_id,product_name,价格,型号,create_time
  2. 网关- gateway_id,gateway_name,create_time
  3. mapping_product_gateways - mapping_id,gateway_id,product_id

产品和网关表没有任何共同之处。没有外键等,但是当我创建一个产品时,我将网关选择字段显示为用网关表中的数据填充的多选择字段。一旦我按下submit按钮来插入产品记录,当时所有所选网关的id都被插入到mapping_product_gateways表中,具有相同的product_id和选定的网关id。

因此,插入后的记录可能如下所示:

产品表记录:

1,产品1,10美元,数字,10/10/2013

2,产品2,13美元,订阅,01/01/2013

网关表记录:

1,Paypal,03/01/2014

2,信用卡,2014年1月1日

3,2离职,2014年01月2日

因此,mapping_product_gateways记录可能如下所示:

mapping_id,gateway_id,product_id

1,2,1

2,3,1

3,1,2

3,2,2

这意味着产品ID 1有与其相关联的网关2和3,产品ID 2有与其关联的网关1和2。

由于映射和产品表之间没有直接关系,如何在存储库类中构建查询来执行搜索、插入、更新记录?还是我需要创建一个单一类型的关系n实体?

我完全是confused..excuse我,但我是非常新的塞弗尼。

谢谢

EN

回答 2

Stack Overflow用户

发布于 2014-01-18 14:53:55

这个问题不是塞弗尼问题,而是一个理论问题。首先,您不应该问自己:“数据库会是什么样的?”更好的问题是:“产品和网关是如何关联的?”

据我所知,您的帖子:-许多产品可以有许多网关。

所以我们说的是多到多的联系。这就是你需要的原因(“数据库会是什么样的?”)将两个表相关联的第三个表。但我们需要回答第二个问题(“产品和网关是如何关联的?”)答:他们是通过一个多到多的联系.

这是如何在理论上实现的?

代码语言:javascript
复制
/**
* @ORM\Entity()
*/
class Product{
    /*
    * @ORM\ManyToMany(targetEntity="Gateway", inversedBy="products")
    */
    private $gateways;
    //adder + setter + getter
}

/**
* @ORM\Entity()
*/
class Gateway{
    /*
    * @ORM\ManyToMany(targetEntity="Product", mappedBy="gateways")
    */
    private $products;
    //adder + setter + getter
}

为了模式更新,请执行php应用程序/控制台原则: schema : update -force in您的cmd (app root dir)

这就是解决问题的方法,学说。不错,不是吗?

你的第二个问题是:我怎么才能和实体打交道?

假设您在控制器中进行编码。您的数据库没有产品,只有5个网关(id1-5)。

代码语言:javascript
复制
class someController extends Controller {
    public function doSomeCrud(){
        $em = $this -> get('doctrine.orm.entity_manager');
        $product = new Product();
        $someGateway = $em -> find('NAMESPACE\Gateway',3);
        $anotherGateway = $em -> find('NAMESPACE\Gateway',5);
        $product -> addGateway($someGateway) -> addGateway($anotherGateway);
        $em -> persist($product);
        $em -> flush();
    }
}

调用该方法后,您的数据库如下所示:

产品:1

网关: 1;2;3;4;5

Product_Gateway:(1,1,3);(2,1,5)

您可以通过以下方式获取产品的所有网关

代码语言:javascript
复制
$product -> getGateways();

并通过以下方式更新产品:

代码语言:javascript
复制
$product -> getGateways() -> first() -> setName('new name');
$em -> flush();

实体管理器确认网关3的名称已更改,并使更新网关集名称=‘新名称’,其中id =3

票数 1
EN

Stack Overflow用户

发布于 2014-01-19 11:49:21

您仍然缺少的是设置器和getter(例如产品->网关):

代码语言:javascript
复制
public function addGateway(GatewayInterface $gateway){
    $this -> gateways -> add($gateway);
    return $this;
}

public function setGateways(Collection $gateway){
    $this -> gateways = $gateways;
    return $this;
}

public function getGateways(){
    return $this -> gateways;
}

您需要首先创建GatewayInterface才能使其工作。对于网关->产品,需要相同的设置器/getter

索引操作(创建产品)必须如下所示:

代码语言:javascript
复制
public function indexAction()
{
    $em = $this->getDoctrine()->getManager();
    $product = new ShopProducts();
    $em -> persist($product);
    $gateway = new GlobalGateways();
    $em -> persist($gateway);
    $product -> addGateway($gateway);
    $em -> flush();
}

注意:您应该始终将类命名为单数。所以如果名字是“产品”和"GlobalGateway“就更好了

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21203015

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档