在doctrine2中你用什么来代替ENUM?

发布于 2024-12-25 07:08:45 字数 83 浏览 0 评论 0原文

在 Doctrine2 中你用什么来代替 ENUM?小整数?我想过使用varchar,或者显式定义char,但这对于索引来说可能不是很有效,还是我错了?

What do you use instead of ENUM in Doctrine2? smallint? I thought of using varchar, or explicitly define char, but this may not be very effective when it comes to indexes, or am I wrong?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

牵你手 2025-01-01 07:08:45

我通常使用映射到类常量的整数,就像

class MyEntity {
    const STATUS_INACTIVE = 0;
    const STATUS_ACTIVE = 1;
    const STATUS_REFUSE = 2;

    protected $status = self::STATUS_ACTIVE;
}

这样工作得很好,并且使得在 IDE 中使用您所谓的 ENUMS 变得更加容易。

您还可以 使用可枚举类型,如下所述通过文档,但这意味着您必须为每个枚举列定义一种自定义类型。这是大量的工作,但没有真正的好处。

您可能还想知道为什么您应该'并没有真正使用枚举

I usually work with integers mapped to class constants, like

class MyEntity {
    const STATUS_INACTIVE = 0;
    const STATUS_ACTIVE = 1;
    const STATUS_REFUSE = 2;

    protected $status = self::STATUS_ACTIVE;
}

That works quite fine and makes it even easier to work with what you would call ENUMS in an IDE.

You can also use an enumerable type as described by the documentation, but that means you will have to define one custom type per enum column. That's a lot of work with no real benefit.

You may also want to know why you shouldn't really use enums.

℡寂寞咖啡 2025-01-01 07:08:45

Postgres、Symfony、ORM、Doctrine...

  1. Postgres:定义新类型枚举 (pgAdmin)

    CREATE TYPE new_enum AS ENUM ('sad', 'ok', 'happy');
    
  2. 在实体中

    @ORM\Column(name="name",type="string",columnDefinition="new_enum", 
    可空=真)
    
  3. 在 config.yml 中

    mapping_types:
        新枚举:字符串
    

     

    # Doctrine 配置
    教义:
        数据库:
            驱动程序:“%database_driver%”
            主机:“%database_host%”
            端口:“%database_port%”
            数据库名称:“%database_name%”
            用户:“%database_user%”
            密码:“%database_password%”
            字符集:UTF8
            映射类型:
                new_enum: string # <========
    

Postgres, Symfony, ORM, Doctrine...

  1. Postgres: Define new type enum (pgAdmin)

    CREATE TYPE new_enum AS ENUM ('sad', 'ok', 'happy');
    
  2. In Entity

    @ORM\Column(name="name", type="string", columnDefinition="new_enum", 
    nullable=true)
    
  3. In config.yml

    mapping_types:
        new_enum: string
    

     

    # Doctrine Configuration
    doctrine:
        dbal:
            driver:   "%database_driver%"
            host:     "%database_host%"
            port:     "%database_port%"
            dbname:   "%database_name%"
            user:     "%database_user%"
            password: "%database_password%"
            charset:  UTF8
            mapping_types:
                new_enum: string # <=======
    
忘羡 2025-01-01 07:08:45

如果您想要使用 MySQL 和 Symfony 的 MySQL ENUM,您现在可以使用一种简单的方法,无需任何依赖项,

为所有枚举使用基类:

<?php

namespace App\Enum;

use Doctrine\DBAL\Types\Type;
use Doctrine\DBAL\Platforms\AbstractPlatform;

abstract class EnumType extends Type
{
    protected $name;
    protected $values = [];

    public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform)
    {
        $values = array_map(function($val) { return "'".$val."'"; }, $this->values);

        return "ENUM(".implode(", ", $values).")";
    }

    public function convertToPHPValue($value, AbstractPlatform $platform)
    {
        return $value;
    }

    public function convertToDatabaseValue($value, AbstractPlatform $platform)
    {
        if (!in_array($value, $this->values)) {
            throw new \InvalidArgumentException("Invalid '".$this->name."' value.");
        }
        return $value;
    }

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

    public function requiresSQLCommentHint(AbstractPlatform $platform)
    {
        return true;
    }
}

针对您的特殊情况扩展它:

namespace App\Enum;

 class UploadFileStatusType extends EnumType
{
     const OPEN = 'open';
     const DONE = 'done';
     const ERROR = 'error';

     protected $name = self::class;

     protected $values = [
         self::OPEN => self::OPEN ,
         self::DONE => self::DONE,
         self::ERROR => self::ERROR,
     ];

}

将其添加到您的 dcotrine.yml 配置文件中:

doctrine:
    dbal:
        types:
            UploadFileStatusType: App\Enum\UploadFileStatusType

在中使用它您的实体文件作为学说列文档类型:

class MyEntity
{
    /**
     * @var string
     *
     * @ORM\Column(type="UploadFileStatusType")
     */
    protected $status;
}

您最终将获得一个干净的 MySQL ENUM 类型来表示列状态:

enum('open', 'done', 'error')

If you want MySQL ENUMs using MySQL and Symfony, you can now use an easy way for that without any dependencies

use a base class for all enums:

<?php

namespace App\Enum;

use Doctrine\DBAL\Types\Type;
use Doctrine\DBAL\Platforms\AbstractPlatform;

abstract class EnumType extends Type
{
    protected $name;
    protected $values = [];

    public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform)
    {
        $values = array_map(function($val) { return "'".$val."'"; }, $this->values);

        return "ENUM(".implode(", ", $values).")";
    }

    public function convertToPHPValue($value, AbstractPlatform $platform)
    {
        return $value;
    }

    public function convertToDatabaseValue($value, AbstractPlatform $platform)
    {
        if (!in_array($value, $this->values)) {
            throw new \InvalidArgumentException("Invalid '".$this->name."' value.");
        }
        return $value;
    }

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

    public function requiresSQLCommentHint(AbstractPlatform $platform)
    {
        return true;
    }
}

extend it for your special case:

namespace App\Enum;

 class UploadFileStatusType extends EnumType
{
     const OPEN = 'open';
     const DONE = 'done';
     const ERROR = 'error';

     protected $name = self::class;

     protected $values = [
         self::OPEN => self::OPEN ,
         self::DONE => self::DONE,
         self::ERROR => self::ERROR,
     ];

}

add it to your dcotrine.yml config file:

doctrine:
    dbal:
        types:
            UploadFileStatusType: App\Enum\UploadFileStatusType

use it in your entity file as doctrine column doc type:

class MyEntity
{
    /**
     * @var string
     *
     * @ORM\Column(type="UploadFileStatusType")
     */
    protected $status;
}

And you will end up with a clean MySQL ENUM type for column status:

enum('open', 'done', 'error')
亚希 2025-01-01 07:08:45

使用 symfony 时,您应该使用 fre5h/DoctrineEnumBundle 作为原则:

使用示例

为新的ENUM类型BasketballPositionType创建一个类:

<?php
namespace App\DBAL\Types;

use Fresh\DoctrineEnumBundle\DBAL\Types\AbstractEnumType;

final class BasketballPositionType extends AbstractEnumType
{
    public const POINT_GUARD = 'PG';
    public const SHOOTING_GUARD = 'SG';
    public const SMALL_FORWARD = 'SF';
    public const POWER_FORWARD = 'PF';
    public const CENTER = 'C';

    protected static $choices = [
        self::POINT_GUARD => 'Point Guard',
        self::SHOOTING_GUARD => 'Shooting Guard',
        self::SMALL_FORWARD => 'Small Forward',
        self::POWER_FORWARD => 'Power Forward',
        self::CENTER => 'Center'
    ];
}

在config.yml中为Doctrine注册BasketballPositionType:

doctrine:
    dbal:
        types:
            BasketballPositionType: App\DBAL\Types\BasketballPositionType

创建一个具有位置字段的Player实体:

<?php
namespace App\Entity;

use App\DBAL\Types\BasketballPositionType;
use Doctrine\ORM\Mapping as ORM;
use Fresh\DoctrineEnumBundle\Validator\Constraints as DoctrineAssert;

/**
 * @ORM\Entity()
 * @ORM\Table(name="players")
 */
class Player
{
    /**
     * @ORM\Id
     * @ORM\Column(name="id", type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * Note, that type of a field should be same as you set in Doctrine config
     * (in this case it is BasketballPositionType)
     *
     * @ORM\Column(name="position", type="BasketballPositionType", nullable=false)
     * @DoctrineAssert\Enum(entity="App\DBAL\Types\BasketballPositionType")     
     */
    protected $position;

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

    public function setPosition(string $position)
    {
        $this->position = $position;
    }

    public function getPosition(): string
    {
        return $this->position;
    }
}

现在您可以在某个动作或其他地方设置玩家的位置:

$player->setPosition(BasketballPositionType::POINT_GUARD);

You should use fre5h/DoctrineEnumBundle for doctrine when using symfony:

Example of using

Create a class for new ENUM type BasketballPositionType:

<?php
namespace App\DBAL\Types;

use Fresh\DoctrineEnumBundle\DBAL\Types\AbstractEnumType;

final class BasketballPositionType extends AbstractEnumType
{
    public const POINT_GUARD = 'PG';
    public const SHOOTING_GUARD = 'SG';
    public const SMALL_FORWARD = 'SF';
    public const POWER_FORWARD = 'PF';
    public const CENTER = 'C';

    protected static $choices = [
        self::POINT_GUARD => 'Point Guard',
        self::SHOOTING_GUARD => 'Shooting Guard',
        self::SMALL_FORWARD => 'Small Forward',
        self::POWER_FORWARD => 'Power Forward',
        self::CENTER => 'Center'
    ];
}

Register BasketballPositionType for Doctrine in config.yml:

doctrine:
    dbal:
        types:
            BasketballPositionType: App\DBAL\Types\BasketballPositionType

Create a Player entity that has a position field:

<?php
namespace App\Entity;

use App\DBAL\Types\BasketballPositionType;
use Doctrine\ORM\Mapping as ORM;
use Fresh\DoctrineEnumBundle\Validator\Constraints as DoctrineAssert;

/**
 * @ORM\Entity()
 * @ORM\Table(name="players")
 */
class Player
{
    /**
     * @ORM\Id
     * @ORM\Column(name="id", type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * Note, that type of a field should be same as you set in Doctrine config
     * (in this case it is BasketballPositionType)
     *
     * @ORM\Column(name="position", type="BasketballPositionType", nullable=false)
     * @DoctrineAssert\Enum(entity="App\DBAL\Types\BasketballPositionType")     
     */
    protected $position;

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

    public function setPosition(string $position)
    {
        $this->position = $position;
    }

    public function getPosition(): string
    {
        return $this->position;
    }
}

Now you can set a position for Player inside some action or somewhere else:

$player->setPosition(BasketballPositionType::POINT_GUARD);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文