理论多对多关系和onFlush事件 [英] Doctrine many-to-many relations and onFlush event

查看:181
本文介绍了理论多对多关系和onFlush事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

关于图书和作者的小例子:
DB结构:

Little example about Books and Authors: DB structure:

实体(它们是使用symfony2控制台命令从数据库生成的):

Entities (they were generated form database using symfony2 console commands):

作者:

    /**
 * Author
 *
 * @ORM\Table(name="authors")
 * @ORM\Entity
 */
class Author
{

    private $_isCachable = true;


    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer", nullable=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;

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

    /**
     * @var \Doctrine\Common\Collections\Collection
     *
     * @ORM\ManyToMany(targetEntity="App\CoreBundle\Entity\Books", mappedBy="author", cascade={"persist","remove","detach","merge","refresh"})
     */
    private $book;

    /**
     * Constructor
     */
    public function __construct()
    {
    $this->book = new \Doctrine\Common\Collections\ArrayCollection();
    }
}

书:

 <?php

namespace App\CoreBundle\Entity;

use App\CoreBundle\RedisLayer\Marks\Insert;
use App\CoreBundle\RedisLayer\Marks\Update;
use Doctrine\ORM\Mapping as ORM;

/**
 * Book
 *
 * @ORM\Table(name="books")
 * @ORM\Entity
 */
class Book
{

    private $_isCachable = true;


    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer", nullable=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="ttile", type="string", length=255, nullable=false)
     */
    private $ttile;

    /**
     * @var string
     *
     * @ORM\Column(name="isbn", type="string", length=255, nullable=false)
     */
    private $isbn;

    /**
     * @var \Doctrine\Common\Collections\Collection
     *
     * @ORM\ManyToMany(targetEntity="App\CoreBundle\Entity\Authors", inversedBy="book", cascade={"persist","remove","detach","merge","refresh"})
     * @ORM\JoinTable(name="author_books",
     *   joinColumns={
     *     @ORM\JoinColumn(name="book_id", referencedColumnName="id")
     *   },
     *   inverseJoinColumns={
     *     @ORM\JoinColumn(name="author_id", referencedColumnName="id")
     *   }
     * )
     */
    private $author;

    /**
     * Constructor
     */
    public function __construct()
    {
    $this->author = new \Doctrine\Common\Collections\ArrayCollection();
    }

}

所以当我运行这段代码:

So when I run this code:

    $book = new \App\CoreBundle\Entity\Book();
    $book->setTtile('book title: '.uniqid());
    $book->setIsbn('book isbn: '.uniqid());

    $author = new \App\CoreBundle\Entity\Author();
    $author->setName('author title: '.uniqid());


    $author->addBook($book);

    $entityManager->persist($author);

    $entityManager->flush();

我希望doctrine生成这些SQL:

I expect doctrine to generate these SQLs:

"START TRANSACTION"]

    # CREATE BOOK
    INSERT INTO books (ttile, isbn) VALUES (?, ?)
    array(2) {
      [1] =>
      string(25) "book title: 524ea3cf34d5f"
      [2] =>
      string(24) "book isbn: 524ea3cf34da3"
    }
    array(2) {
      [1] =>
      string(6) "string"
      [2] =>
      string(6) "string"
    }

    # CREATE AUTHOR
    INSERT INTO authors (name) VALUES (?)
    array(1) {
      [1] =>
      string(27) "author title: 524ea3cf34de9"
    }
    array(1) {
      [1] =>
      string(6) "string"
    }

    # CREATE LINKS
    INSERT INTO author_books (book_id, author_id) VALUES (?, ?)
    array(2) {
      [0] =>
      int(34)
      [1] =>
      int(23)
    }

"COMMIT"

但是,我只得到#CERATE AUTHOR和#CREATE BOOK的SQL。没有生成链接表的SQL。

But i get only SQLs for #CERATE AUTHOR and #CREATE BOOK. SQL for linking table was not generated.


  1. 有什么问题?

  1. What is the problem?

如果我运行这段代码:

$book = new \App\CoreBundle\Entity\Book();
$book->setTtile('book title: '.uniqid());
$book->setIsbn('book isbn: '.uniqid());

$author = new \App\CoreBundle\Entity\Author();
$author->setName('author title: '.uniqid());

$author->addBook($book);
$book->addAuthor($author); // added

$entityManager->persist($author);

$entityManager->flush();

都可以。所以我需要添加书籍作者和作者来预订?可以创建书籍和作者,然后预订作者和刷新(不需要添加作者来预订)?

all is OK. So I need to add book to author and author to book? Is it possible to create book and author and then and book to author and flush (without adding author to book) ?

如果我在flush事件侦听器上使用doctrine可以使用 getScheduledEntityUpdates (应该更新的实体列表), getScheduledEntityInsertions (应该更新的实体列表)和 getScheduledEntityDeletions (应删除的实体列表)unitOfWork对象的方法。但这只是实体。如何获取有关链接表的信息?

If I use doctrine onFLush event listener I can use getScheduledEntityUpdates (list of entities that should be updated), getScheduledEntityInsertions (list of entities that should be updated) and getScheduledEntityDeletions (list of entities that should be deleted) methods of the unitOfWork object. But this is only entities. How can I get info about linking table? I need to get SQL for linking table at doctrine onFlush event.


推荐答案

我需要获取SQL链接表在doctrine onFlush事件。您需要确保Book:作者和作者:书籍在持续存在之前具有适当的价值。

You need to ensure that both Book:authors and Author:books have the proper values before persisting.

具体来说:

class Authors
{
    public function addBook($book)
    {
        $this->books[] = $book;
        $book->addAuthor($this);
    }

在Book实体上执行相同操作。

Do the same on the Book entity.

BTW,将书籍和作者更改为书籍和作者。否则会让你疯狂。如果需要,您可以保留表名复数。

BTW, change Books and Authors to Book and Author. Otherwise it will drive you crazy. You can keep the table names plural if you want.

==================== ==========================

====================================================

问题#3:

当doctrine创建一个链接表时,它完全隐藏它。您需要做的是创建自己的BookAuthor实体,然后将一个多个关系从它设置为Book / Author。在这一点上,您将完全访问它。如果需要,您还可以添加其他属性。

When doctrine creates a linking table then it hides it completely. What you need to do is to make your own BookAuthor entity and then set one to many relations from it to Book/Author. At that point you will have full access to it. You can also add additional properties if you want.

这篇关于理论多对多关系和onFlush事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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