📜  一对多关系返回具有空数组集合的持久集合 symfony (1)

📅  最后修改于: 2023-12-03 15:35:52.223000             🧑  作者: Mango

一对多关系返回具有空数组集合的持久集合 symfony

在 Symfony 中,实现一对多关系时,通常需要使用到一个持久集合(collection)。持久集合是 Doctrine 在查询并返回一组关系实体时使用的一种集合类型。

但是在某些情况下,可能需要返回一个空的持久集合。本文将介绍如何在 Symfony 中实现具有空数组集合的持久集合。

创建一对多关系

首先,我们需要创建一个具有一对多关系的实体类。在本例中,我们将创建一个 User 实体,它可以拥有多个 Address 实体:

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity()
 */
class User
{
    /**
     * @ORM\Id
     * @ORM\GeneratedValue
     * @ORM\Column(type="integer")
     */
    private int $id;

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

    /**
     * @ORM\OneToMany(targetEntity="Address", mappedBy="user")
     */
    private Collection $addresses;

    public function __construct()
    {
        $this->addresses = new ArrayCollection();
    }

    // ...
}

请注意,我们在 $addresses 属性中使用了 Collection 类型,并在构造函数中初始化了一个 ArrayCollection 对象。

接下来,我们需要创建一个 Address 实体,它将保存 User 实体的地址信息:

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity()
 */
class Address
{
    /**
     * @ORM\Id
     * @ORM\GeneratedValue
     * @ORM\Column(type="integer")
     */
    private int $id;

    /**
     * @ORM\Column(type="string")
     */
    private string $street;

    /**
     * @ORM\Column(type="string")
     */
    private string $city;

    /**
     * @ORM\ManyToOne(targetEntity="User", inversedBy="addresses")
     * @ORM\JoinColumn(nullable=false)
     */
    private User $user;

    // ...
}

请注意,我们在 $user 属性中使用了 User 类型,并使用 ManyToOne 注解来表示多个 Address 实体属于同一个 User 实体。

如果您已经熟悉了一对多关系的创建方式,则可以跳过下一节,并开始阅读下一节的内容。

查询一对多关系

要查询 User 实体及其关联的 Address 实体,可以使用以下代码:

$repository = $entityManager->getRepository(User::class);
$user = $repository->findOneBy(['id' => $userId]);

$addresses = $user->getAddresses();
foreach ($addresses as $address) {
    echo $address->getStreet() . "\n";
}

请注意,我们可以使用 getAddresses() 方法来获取 User 实体的地址集合。如果用户没有地址,则此方法将返回一个空的 ArrayCollection 对象。

但是,如果您想在没有地址的情况下返回一个空的持久集合,则可以在 User 实体类中执行以下更改:

/**
 * @ORM\Entity()
 */
class User
{
    // ...

    public function getAddresses(): Collection
    {
        return $this->addresses ?: new ArrayCollection();
    }

    // ...
}

在这个实现中,我们将 getAddresses() 方法中的 return 语句更改为返回 $addresses ?: new ArrayCollection()。如果 $addresses 属性为 null 或空,则返回一个新的空 ArrayCollection 对象。

现在,我们可以使用上面的查询代码,并且即使用户没有地址,getAddresses() 方法也始终返回一个空的持久集合:

$repository = $entityManager->getRepository(User::class);
$user = $repository->findOneBy(['id' => $userId]);

$addresses = $user->getAddresses();
if ($addresses->isEmpty()) {
    echo "User has no addresses.\n";
} else {
    foreach ($addresses as $address) {
        echo $address->getStreet() . "\n";
    }
}

使用上述代码,即使用户没有地址,也会输出 User has no addresses.

结论

在 Symfony 中实现具有空数组集合的持久集合是一个简单的过程,只需要在实体类中添加一个新的 getAddresses() 方法即可。

特别注意,在查询 User 实体的地址集合时,应该检查 $addresses 属性是否为 null 或空,以确保在没有地址的情况下返回一个空的持久集合。