在doctrine2中你用什么而不是ENUM?

时间:2012-01-05 22:22:17

标签: symfony doctrine-orm

你在Doctrine2中用什么代替ENUM? SMALLINT?我想过使用varchar,或者明确定义char,但是在索引方面这可能不是很有效,或者我错了吗?

4 个答案:

答案 0 :(得分:63)

我通常使用映射到类常量的整数,比如

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

    protected $status = self::STATUS_ACTIVE;
}

这非常好用,可以更轻松地使用IDE中的ENUMS。

您也可以use an enumerable type as described by the documentation,但这意味着您必须为每个枚举列定义一个自定义类型。这是很多工作,没有真正的好处。

您可能还想知道why you shouldn't really use enums

答案 1 :(得分:8)

Postgres,symfony,orm,doctrine ......

  1. Postgress定义新类型枚举(pgAdmin)
  2.   

    CREATE TYPE new_enum AS ENUM('sad','ok','happy');

    1. 在实体
    2.   

      @ORM \ Column(name =“name”,type =“string”,columnDefinition =“new_enum”,   可空=真)

      1. 在config.yml
      2.   

        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 # <=======
        

答案 2 :(得分:2)

如果您想要使用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

在您的实体文件中将其用作教义列doc类型:

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

最后,您将得到一个干净的MySQL ENUM类型的列状态:

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

答案 3 :(得分:-1)

使用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中为学说注册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设置位置:

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