在 Doctrine 中映射 class 名称
Mapping class name in Doctrine
我正在构建一个应用程序,其中包含一个名为 Element
的对象。 class由2个字段组成(其实还有很多,其他的无关紧要):
ElementData
- 一组具有一些附加功能的数据(键-值)
ElementType
- 与多个实现的接口。封装的一组业务规则和验证器 - 没有获得任何值
简化的class图表:
我很少有 classes 实现 ElementType
接口:
class Type1 implements ElementType {/*...*/}
class Type2 implements ElementType {/*...*/}
class Type3 implements ElementType {/*...*/}
我的元素数据库table也很简单,只有2个相关字段(其余部分从屏幕截图中删除):
问题来了。我不知道如何映射 class (Type1, Type2...) 并将其保存为 elements
table 中的字符串 (type1, type2...) (如普通嵌入元素)。我搜索了文档,没有找到任何有用的东西。
我当前的映射文件如下所示:
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
https://raw.github.com/doctrine/doctrine2/master/doctrine-mapping.xsd">
<entity name="App\Domain\Element" table="elements" repository-class="App\Repository\ElementRepository">
<embedded name="id" class="App\Domain\ElementId" use-column-prefix="false" />
<!--Missing mapping here-->
</entity>
</doctrine-mapping>
我终于明白了。也许我的解决方案对某人有帮助。该解决方案基于 custom mapping type.
<?php
namespace App\Mapping;
use App\Domain\ElementType;
use App\Domain\Type1;
use App\Domain\TypeFactory;
use Doctrine\DBAL\Types\Type;
use Doctrine\DBAL\Platforms\AbstractPlatform;
class ElementType extends Type
{
const NAME = 'element_type';
public function getSQLDeclaration(array $column, AbstractPlatform $platform)
{
return $platform->getVarcharTypeDeclarationSQL($column);
}
public function convertToPHPValue($value, AbstractPlatform $platform)
{
return TypeFactory::getTypeByString($value);
}
public function convertToDatabaseValue($value, AbstractPlatform $platform)
{
if (!$value instanceof ElementType) {
throw new \Exception('Wrong type');
}
return TypeFactory::getStringByType($value);
}
public function getName(): string
{
return self::NAME;
}
}
TypeFactory
只是一个简单的switch语句,这里就不贴了。
# config/packages/doctrine.yml
doctrine:
dbal:
types:
element_type: App\Mapping\ElementType
创建自定义映射类型后,我所要做的就是在我的映射器中实现它:
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
https://raw.github.com/doctrine/doctrine2/master/doctrine-mapping.xsd">
<entity name="App\Domain\Element" table="elements" repository-class="App\Repository\ElementRepository">
<embedded name="id" class="App\Domain\ElementId" use-column-prefix="false" />
<field name="type" type="element_type" />
</entity>
</doctrine-mapping>
我正在构建一个应用程序,其中包含一个名为 Element
的对象。 class由2个字段组成(其实还有很多,其他的无关紧要):
ElementData
- 一组具有一些附加功能的数据(键-值)ElementType
- 与多个实现的接口。封装的一组业务规则和验证器 - 没有获得任何值
简化的class图表:
我很少有 classes 实现 ElementType
接口:
class Type1 implements ElementType {/*...*/}
class Type2 implements ElementType {/*...*/}
class Type3 implements ElementType {/*...*/}
我的元素数据库table也很简单,只有2个相关字段(其余部分从屏幕截图中删除):
问题来了。我不知道如何映射 class (Type1, Type2...) 并将其保存为 elements
table 中的字符串 (type1, type2...) (如普通嵌入元素)。我搜索了文档,没有找到任何有用的东西。
我当前的映射文件如下所示:
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
https://raw.github.com/doctrine/doctrine2/master/doctrine-mapping.xsd">
<entity name="App\Domain\Element" table="elements" repository-class="App\Repository\ElementRepository">
<embedded name="id" class="App\Domain\ElementId" use-column-prefix="false" />
<!--Missing mapping here-->
</entity>
</doctrine-mapping>
我终于明白了。也许我的解决方案对某人有帮助。该解决方案基于 custom mapping type.
<?php
namespace App\Mapping;
use App\Domain\ElementType;
use App\Domain\Type1;
use App\Domain\TypeFactory;
use Doctrine\DBAL\Types\Type;
use Doctrine\DBAL\Platforms\AbstractPlatform;
class ElementType extends Type
{
const NAME = 'element_type';
public function getSQLDeclaration(array $column, AbstractPlatform $platform)
{
return $platform->getVarcharTypeDeclarationSQL($column);
}
public function convertToPHPValue($value, AbstractPlatform $platform)
{
return TypeFactory::getTypeByString($value);
}
public function convertToDatabaseValue($value, AbstractPlatform $platform)
{
if (!$value instanceof ElementType) {
throw new \Exception('Wrong type');
}
return TypeFactory::getStringByType($value);
}
public function getName(): string
{
return self::NAME;
}
}
TypeFactory
只是一个简单的switch语句,这里就不贴了。
# config/packages/doctrine.yml
doctrine:
dbal:
types:
element_type: App\Mapping\ElementType
创建自定义映射类型后,我所要做的就是在我的映射器中实现它:
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
https://raw.github.com/doctrine/doctrine2/master/doctrine-mapping.xsd">
<entity name="App\Domain\Element" table="elements" repository-class="App\Repository\ElementRepository">
<embedded name="id" class="App\Domain\ElementId" use-column-prefix="false" />
<field name="type" type="element_type" />
</entity>
</doctrine-mapping>