symfony7中使用enum类型, 为什么需要如下的配置,那是因为默认doctrine不支持enum类型,需要这么一个映射配置:
1>配置 mapping_types 中的 enum 为 string 在 Doctrine 和 Symfony 中处理 ENUM 类型字段时是一个常见做法,因为它允许 Doctrine 将数据库中的 ENUM 类型映射为 PHP 中的字符串类型,并正常操作该字段的值。
doctrine:
dbal:
connections:
default:
# 其他 DB 配置
mapping_types:
enum: string
作用详解
在这种配置下,Doctrine 会将 MySQL 中的 ENUM 类型映射为 string,这样您可以在代码中直接以字符串的形式读取和操作 ENUM 字段,而不必自定义 Doctrine 类型来专门支持 ENUM。这一设置将自动应用于所有包含 ENUM 类型的字段,不会影响现有的字段操作。
配合 columnDefinition 使用
当您在实体中用 columnDefinition 定义 ENUM 字段类型时:
#[ORM\Column(name: 'title', type: 'string', columnDefinition: "ENUM('Single-line text', 'Multi-line text', 'Single choice', 'Multiple choices')")]
private string $title;
Doctrine 会在数据库中将 title 字段创建为 ENUM 类型,同时,在 PHP 中该字段的类型为 string。通过 mapping_types 配置的映射关系,Doctrine 能够识别数据库中的 ENUM 并将其当作 string 处理,不会导致类型不兼容的问题。
这样配置的好处
- 无需额外类型定义:避免为
ENUM创建自定义 Doctrine 类型。 - 数据库兼容性:适用于使用 MySQL 数据库的项目,保持数据库层面的数据约束。
- 便捷操作:在代码中直接以
string类型操作ENUM字段的值,符合 PHP 的使用习惯。
总结
配置 mapping_types 来将 enum 映射为 string,可以让您在 Symfony 和 Doctrine 中轻松地定义和操作数据库的 ENUM 字段,且不会丢失数据库约束。
2>在 Symfony 7 和 Doctrine 中,您可以使用 columnDefinition 来为 enum 字段定义自定义的 SQL 类型。以下是这个定义的作用和相关注意事项:
作用
通过以下定义:
#[ORM\Column(name: 'title', type: 'string', columnDefinition: "ENUM('Single-line text', 'Multi-line text', 'Single choice', 'Multiple choices')")]
private string $title;
您为 title 字段指定了一个 ENUM 数据类型,这样做会在数据库中直接创建一个 ENUM 类型的字段,其可选值为 'Single-line text', 'Multi-line text', 'Single choice', 'Multiple choices'。字段在数据库层面上将被限制为这些值,任何其他值都会导致数据库约束错误。
注意事项
直接定义 ENUM:
- 使用
columnDefinition定义ENUM类型,能够利用数据库的原生ENUM特性,实现更严格的数据约束。 - 这种方式不会影响 Doctrine 实体的使用,您可以直接读取和设置
title字段为字符串值,例如$title = 'Single-line text'。
- 使用
数据库兼容性:
ENUM类型是 MySQL 的特性,如果您的项目需要支持其他数据库(如 PostgreSQL、SQLite),则此配置可能会导致兼容性问题,因为其他数据库可能不支持ENUM或实现方式不同。- 如果有跨数据库需求,建议使用
VARCHAR类型加上代码级别的校验。
更新迁移:
- 如果以后需要增加或修改
ENUM的选项,您需要手动更新数据库列。Doctrine 的自动迁移工具(如doctrine:migrations:diff)可能不会自动检测ENUM选项的变化,您可能需要编写自定义 SQL 语句来更新这些选项。
- 如果以后需要增加或修改
使用代码校验(可选):
- 虽然数据库会约束
title字段的值,但在应用层面,也可以在 Symfony 实体中进行值校验,防止在到达数据库之前写入不符合ENUM定义的值。
- 虽然数据库会约束
示例用法
在应用中,您可以正常读取和设置 title 字段的值:
$user = new User();
$user->setTitle('Single choice');
echo $user->getTitle(); // 输出: Single choice
这样使用可以很好地将数据库约束和代码逻辑结合起来,以确保数据一致性和正确性。
