主页/PHP笔记/PHP问答/框架Symfony/Doctrine:如何定义一个实体

Doctrine:如何定义一个实体

Bug编译狮

Bug编译狮

Doctrine 是一个用于 PHP 的 ORM(对象关系映射)框架,它允许开发者将数据库表映射到类中,并提供了一种声明式的方式来操作数据库数据。要定义一个实体,你需要遵循以下几个步骤:

  1. 安装 Doctrine: 首先,确保你已经安装了 Doctrine。你可以通过 Composer 来安装:

    composer require doctrine/orm
  2. 创建实体类: 在你的项目目录下创建一个新的文件夹来存放你的实体类。例如,src/Entity

  3. 定义实体类: 在 src/Entity 文件夹中创建一个新的 PHP 文件,例如 User.php。在这个文件中,定义你的实体类。

    <?php
    
    namespace AppEntity;
    
    use DoctrineORMMapping as ORM;
    
    /**
    * @ORMEntity(repositoryClass="AppRepositoryUserRepository")
    */
    class User
    {
       /**
        * @ORMId
        * @ORMGeneratedValue(strategy="AUTO")
        * @ORMColumn(type="integer")
        */
       private $id;
    
       /**
        * @ORMColumn(type="string", length=255)
        */
       private $username;
    
       /**
        * @ORMColumn(type="string", length=255)
        */
       private $email;
    
       // Getters and Setters
       public function getId(): ?int
       {
           return $this->id;
       }
    
       public function setUsername(string $username): self
       {
           $this->username = $username;
           return $this;
       }
    
       public function getEmail(): ?string
       {
           return $this->email;
       }
    
       public function setEmail(string $email): self
       {
           $this->email = $email;
           return $this;
       }
    }
  4. 配置实体类: 为了使 Doctrine 能够识别和管理你的实体类,你需要在 config/doctrine.yaml 文件中进行配置。

    doctrine:
       orm:
           mappings:
               AppEntity:
                   is_bundle: false
                   type: annotation
                   dir: '%kernel.project_dir%/src/Entity'
                   prefix: 'AppEntity'
  5. 运行迁移命令: 生成数据库表的 SQL 语句并应用它们。

    php bin/console doctrine:migrations:generate
    php bin/console doctrine:migrations:migrate

现在,你已经成功地定义了一个 Doctrine 实体。你可以使用这个实体类来创建、读取、更新和删除数据库记录。例如,以下是如何创建一个新用户的示例代码:

<?php

namespace AppController;

use AppEntityUser;
use DoctrineORMEntityManagerInterface;
use SymfonyBundleFrameworkBundleControllerAbstractController;
use SymfonyComponentHttpFoundationRequest;

class UserController extends AbstractController
{
    private $entityManager;

    public function __construct(EntityManagerInterface $entityManager)
    {
        $this->entityManager = $entityManager;
    }

    public function createUser(Request $request)
    {
        $user = new User();
        $form = $this->createForm(UserType::class, $user);
        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            $this->entityManager->persist($user);
            $this->entityManager->flush();

            return $this->redirectToRoute('user_show', ['id' => $user->getId()]);
        }

        return $this->render('user/create.html.twig', [
            'form' => $form->createView(),
        ]);
    }
}

这个示例展示了如何在控制器中使用实体类来处理用户创建请求。

黑板Bug讲师

黑板Bug讲师

概述

Doctrine 是一个强大的 PHP 对象关系映射器(ORM),主要用于与 Symfony 框架结合使用,但也可以作为独立的库使用。在这篇教程中,我们将探索如何在 Doctrine 中定义实体,包括从基础到高级的各种用法示例。实体代表 Doctrine 中的业务对象,可以在数据库中持久化存储。

在深入定义实体之前,您应该对PHP和面向对象编程(OOP)有一个基本的理解。此外,您需要有一个Doctrine ORM的安装,并且配置了数据库连接。

定义基本实体。

在最基本的层次上,Doctrine中的实体就是一个映射到数据库表的PHP类。以下是一个表示产品的简单示例:

<?php
use DoctrineORMMapping as ORM;

/** 
 * @ORMEntity
 * @ORMTable(name="products")
 */
class Product
{
    /** 
     * @ORMId
     * @ORMGeneratedValue
     * @ORMColumn(type="integer")
     */
    private $id;

    /** 
     * @ORMColumn(type="string")
     */
    private $name;

    // Getters and setters
    public function getId()
    {
        return $this->id;
    }

    public function setName($name)
    {
        $this->name = $name;
    }

    public function getName()
    {
        return $this->name;
    }
}

这段代码片段定义了一个简单的实体,包含两个属性:ID和名称。在ORMEntity注解上声明的类告诉Doctrine这个类是一个实体。在ORM@Table注解上定义了数据库表名。

利用关系

实体通常与其他实体有关系。让我们在我们的Product实体上添加一个多对一的关系,将其与Category实体关联起来:

// ... existing Product class

/**
 * @ORMManyToOne(targetEntity="Category")
 * @ORMJoinColumn(name="category_id", referencedColumnName="id")
 */
private $category;

// ... Getters and setters for category

@ORMManyToMany(targetEntity=”Category”) 表示Product和Category之间的多对多关系,而@ORMJoinColumn(name=”category_id”, referencedColumnName=”id”) 则指定了关联的外键列名和对应的主键字段名。

处理复杂的人际关系

Doctrine提供了多种关系类型,如一对一、一对多和多对多。让我们添加一个双向的一对多关系,映射产品到多个评论:

/**
 * @ORMOneToMany(targetEntity="Review", mappedBy="product")
 */
private $reviews;

public function __construct() {
    $this->reviews = new DoctrineCommonCollectionsArrayCollection();
}

// ... Getters and setters for reviews 

这建立了“一对一”关系,即一个产品可以有多个评论。mappedBy 属性指向关系的一侧。

高级地图选项

实体可以进一步自定义,使用高级选项。例如,告诉Doctrine只加载关联实体时延迟加载,或者指定唯一约束:

/**
 * @ORMEntity
 * @ORMTable(name="products", uniqueConstraints={@ORMUniqueConstraint(name="product_name_unique", columns={"name"})})
 */
class Product
{
    // ... Class content remains the same
}

//Specify lazy loading for the relationship
/**
 * @ORMManyToOne(targetEntity="Category", fetch="LAZY")
 * @ORMJoinColumn(name="category_id", referencedColumnName="id")
 */
private $category;

唯一约束选项确保产品名称在products表内是唯一的。ManyToOne关系中的fetch设置为LAZY,意味着Doctrine只有当访问Category实体时才会加载它。

Doctrina Callbacks Lifecycle

Doctrine 提供了生命周期回调,这些方法可以在实体的生命周期中的特定点被自动调用,例如在保存到数据库之前或从数据库加载之后。要利用这些功能,请在您的实体中定义它们并配置 Doctrine 使用它们:

/**
 * @ORMHasLifecycleCallbacks()
 */
class Product
{
    // ...

    /**
     * @ORMPrePersist
     */
    public function setCreatedAtValue()
    {
        if(!$this->createdAt) {
            $this->createdAt = new DateTime();
        }
    }
    // ...
}

在上述示例中,setCreatedAtValue() 方法将在 Doctrine 持久化实体之前被调用,自动设置一个创建时间戳(如果该字段为 NULL)。

与索引工作

你可以为实体定义索引以提高性能。在这里,我们在产品表的名称列上添加了一个索引:

/**
 * @ORMEntity
 * @ORMTable(name="products", indexes={@ORMIndex(name="product_name_index", columns={"name"})})
 */
class Product
{
    // ... Existing content
}

索引在处理大型数据集或频繁搜索或连接列的场景尤其重要。

结论。

定义实体是使用Doctrine ORM进行工作的重要基础。在本教程中,我们已经讨论了创建实体、处理关系、添加高级映射选项、使用生命周期回调以及索引等内容。Doctrine的实体使您能够以面向对象的PHP方式与数据库交互,从而获得结构化和强大的方法来操作数据。记住,每个实体都应该有一个明确的目的,并且应该反映您的数据库结构。有了这些概念和示例,您就可以掌握定义Doctrine实体的艺术了。

长工码奴1523

长工码奴1523

要在 Doctrine 中定义一个实体,你需要遵循以下步骤:

  1. 首先确保已经安装了 Doctrine 和 Doctrine 2 的 PHP 版本。
  2. 在你的项目中创建一个新的 Doctrine 表格映射文件(通常命名为 doctrine.php),并在其中添加你的实体类。
<?php

namespace AppEntity;

use DoctrineORMMapping as ORM;
use SymfonyComponentValidatorConstraints as Assert;

/**
 * @ORMEntity(repositoryClass="AppRepositoryUserRepository")
 */
class User
{
    /**
     * @ORMId
     * @ORMGeneratedValue
     * @ORMColumn(type="integer")
     */
    private $id;

    /**
     * @ORMColumn(type="string", length=50)
     * @AssertNotBlank(message="Username is required.")
     */
    private $username;

    /**
     * @ORMColumn(type="string", length=50, nullable=true)
     */
    private $email;

    /**
     * @ORMColumn(type="string", length=150, nullable=true)
     */
    private $password;

    /**
     * @ORMColumn(type="datetime")
     */
    private $createdAt;

    public function getId(): ?int
    {
        return $this->id;
    }

    public function getUsername(): ?string
    {
        return $this->username;
    }

    public function setUsername(string $username): self
    {
        $this->username = $username;

        return $this;
    }

    public function getEmail(): ?string
    {
        return $this->email;
    }

    public function setEmail(?string $email): self
    {
        $this->email = $email;

        return $this;
    }

    public function getPassword(): ?string
    {
        return $this->password;
    }

    public function setPassword(?string $password): self
    {
        $this->password = $password;

        return $this;
    }

    public function getCreatedAt(): ?DateTimeInterface
    {
        return $this->createdAt;
    }

    public function setCreatedAt(DateTimeInterface $createdAt): self
    {
        $this->createdAt = $createdAt;

        return $this;
    }
}

在这个例子中,我们定义了一个名为 User 的实体,并使用了 @ORMEntity 注解来指示它是 Doctrine 表格的主体。我们还设置了表字段,如 ID、用户名、电子邮件和密码等。注意,我们还提供了验证约束来检查这些字段是否为非空。

示例代码

假设你有一个用户模型需要保存到数据库中,你可以这样做:

// Model/User.php
namespace AppModel;

use DoctrineCommonCollectionsArrayCollection;
use DoctrineORMMapping as ORM;

/**
 * Class User
 * @package AppModel
 * @ORMEntity(repositoryClass="AppRepositoryUserRepository")
 */
class User
{
    // ...
}

// Repository/UserRepository.php
namespace AppRepository;

use DoctrineBundleDoctrineBundleRepositoryServiceEntityRepository;
use DoctrinePersistenceManagerRegistry;

/**
 * Class UserRepository
 * @package AppRepository
 * @method User|null find($id, $lockMode = null, $lockVersion = null)
 * @method User|null findOneBy(array $criteria, array $orderBy = null)
 * @method User[]    findAll()
 * @method User[]    findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
 */
class UserRepository extends ServiceEntityRepository
{
    public function __construct(ManagerRegistry $registry)
    {
        parent::__construct($registry, 'app_user');
    }
}

// Controller/Controller.php
namespace AppController;

use AppEntityUser;
use AppFormUserType;
use AppRepositoryUserRepository;
use SymfonyBundleFrameworkBundleControllerAbstractController;
use SymfonyComponentHttpFoundationRequest;
use SymfonyComponentHttpFoundationResponse;
use SymfonyComponentRoutingAnnotationRoute;

/**
 * @Route("/users")
 */
class UserController extends AbstractController
{
    /**
     * @Route("/", name="users_index", methods={"GET"})
     */
    public function index(UserRepository $userRepository): Response
    {
        $users = $userRepository->findAll();

        return $this->render('users/index.html.twig', [
            'users' => $users,
        ]);
    }
}

以上就是在 Doctrine 中定义实体的基本步骤。这只是一个基本的例子,实际应用可能会根据具体需求进行修改。