Symfony |需要学说帮助 - 插入多个表格

时间:2014-01-18 10:43:44

标签: symfony doctrine-orm

我有3张桌子:

  1. 产品 - product_id,product_name,price,type,create_time
  2. 网关 - gateway_id,gateway_name,create_time
  3. mapping_product_gateways - mapping_id,gateway_id,product_id
  4. 产品和网关表没有任何共同之处。没有外键等。但是当我创建产品时,我将网关选择字段显示为多选字段,其中填充了来自网关表的数据。一旦我点击提交按钮插入产品记录,那时所有选定网关的ID都会插入到mapping_product_gateways表中,并且具有相同的product_id和选定的网关ID。

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

    产品表记录:

    1,产品1,$ 10,数字,10/10 / 2013

    2,产品2,13美元,订阅,2013年1月1日

    网关表记录:

    1,Paypal,03/01/2014

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

    3,2 Checking,02/01/2014

    因此,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和1。 2与之相关。

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

    我完全糊涂了..对不起,但我对symfony很新。

    由于

2 个答案:

答案 0 :(得分:1)

这个问题不是一个symfony问题,而是一个学说问题。 首先,您不应该问自己"数据库将如何显示?"。更好的问题是:"产品和网关如何关联?"

据我了解你的帖子: - 许多产品可以有很多网关。

所以我们谈论的是多对多关联。这就是你需要的原因("数据库将如何显示?")第三个关联两个表的表。 但我们需要回答第二个问题("产品和网关如何关联?") 答:它们通过多对多关联来关联。

这是如何在学说中实现的?

/**
* @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 app / console doctrine:schema:update --force in cmd(app root dir)

这就是方式,学说解决了这个问题。很好,不是吗?

你的第二个问题是:我如何与实体进行CRUD?

让我们在控制器中说出你的编码。您的数据库没有产品,但有5个网关(ids 1-5)

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)

您可以通过

获取产品的所有网关
$product -> getGateways();

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

$product -> getGateways() -> first() -> setName('new name');
$em -> flush();

实体经理认识到网关3的名称已更改并生成UPDATE网关设置名称='新名称' WHERE id = 3

答案 1 :(得分:0)

您仍然缺少的是设置者和获取者(产品示例 - >网关):

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才能使其正常工作。 而且你需要为网关提供相同的setter / getters - >产品

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

public function indexAction()
{
    $em = $this->getDoctrine()->getManager();
    $product = new ShopProducts();
    $em -> persist($product);
    $gateway = new GlobalGateways();
    $em -> persist($gateway);
    $product -> addGateway($gateway);
    $em -> flush();
}

注意:您应该始终以单数命名您的类。因此,如果名称是“Product”和“GlobalGateway”

会更好