当前位置: 首页 > 知识库问答 >
问题:

Doctrine2本机查询不支持自定义类型

阎知
2023-03-14

在ZF2-PostgreSQL应用程序中,我想使用Doctrine2本机查询来构建分页器列表。

因此,如果选择了任何自定义的Doctrine/Pgsql类型,它都会非常有效。但对于一个查询,我将使用来自自定义类型的数据。

我在PostgreSQL中声明了一个名为AlertRecipient的Doctrine 2自定义类型,如下所示:

CREATE TYPE alert_recipient AS (
    email text,
    status int
);

这种类型在某些表中使用。客户端表中的示例:

ID (int) | name (varchar) | alerts (alert_recipients[])
1        | John Doe       | {"(john@doe.com, 1), (jane@doe.com, 1)"} 
2        | Foo Bar        | {"(foo@bar.com, 1)"} 

alert_recipient[])

此类型链接到实体,以便:

class AlertRecipient
{
    protected $email;

    protected $status;

    // ... with accessors
}

onBoostrap事件上进行条令类型注册:

// ...
if (!Type::hasType('alert_recipient'))
{
    Type::addType('alert_recipient', AlertRecipient::class);
}
$platform->registerDoctrineTypeMapping('alert_recipient', 'alert_recipient');

if (!Type::hasType('alert_recipient[]'))
{
    Type::addType('alert_recipient[]', AlertRecipients::class);
}
$platform->registerDoctrineTypeMapping('_alert_recipient', 'alert_recipient[]');
// ...

已编写自定义类型适配器,如dochttp://docs.doctrine-project.org/projects/doctrine-orm/en/latest/cookbook/custom-mapping-types.html

查询如下所示:

$rsm = new ResultSetMappingBuilder($em);

$rsm->addRootEntityFromClassMetadata(Client::class, 'c');
// ... some other data from join entity (e.g)

$query = 'SELECT c.* FROM clients c JOIN ...';
$em->createNativeQuery($query, $rsm);

$results = $query->getResult(NativeQuery::HYDRATE_ARRAY);

问题是,从find()Doctrine本机方法,或者从本机查询结果的水合作用,我没有相同的行为。

在自定义类型适配器中调试:

public function convertToPHPValue($value, AbstractPlatform $platform)
{
    var_dump($value); exit;
    // ...
}

编辑

public function convertToPHPValueSQL($sqlExpr, $platform)
{
    return 'to_json(' . $sqlExpr . ')';
}

fint(),结果被正确水合使用AlertRecipient实体:string'[{电子邮件:"john@doe.com","状态": 1},{电子邮件:"jane@doe.com","状态": 1}]'

从本机查询水合作用来看,AlertRecipient实体:string'{(john@doe.com, 1), (jane@doe.com,1)“}”

那么数据的水合作用就不正确了。。。

谢谢你的想法

编辑

Client实体中的alertRecipient属性声明:

/* @ORM\Column(type="alert_recipient[]", nullable=true, name="alert_recipients")
 * @Gedmo\Versioned
 */
 protected $alertRecipients = [];

 // ... with accessors 

共有1个答案

冉德元
2023-03-14

您是否遵循了定制映射类型的原则2文档?

您应该使用像convertToPHPValueconvertToDatabaseValue这样的方法才能正常工作。

你还写道:

find(),使用AlertRecipient实体正确地水合结果。。。

正如我所理解的,AlertRecipient是一个dbal类型类,而不是Entity类。

类型类(所以您的AlertRecipient类)应该扩展Doctrine\DBAL\Types\Type

然后,您应该在使用此类型的实体定义中,用正确的类型属性标记列:

/** @Column(type="alert_recipient") */
$alertRecipient;

因为你没有分享所有的细节(例如,你使用自定义类型的实体定义),我不确定你哪里出错了,但是如果你按照留档,所有这些都应该像预期的那样工作,所以我猜你会跳过其中一个步骤...

 类似资料:
  • 我正在尝试使用条令2查询生成器创建以下场景 我设置了Doctrine2自行生成的以下关系 这是我的回购课 但我没能完成。它抛出以下错误 [Tue Oct01 22:30:11 2013][错误][客户端127.0.0.1]PHP致命错误:未捕获异常'Doctrine\ORM\Query\QueryExc0019',消息'SELECT p from Entity\Tree p LEFT JOIN p

  • 为了计算添加到DB表名称中的项数,我使用了一个带有Spring JPA的本机查询: DTO对象,应该包含在返回的列表中: 我似乎没有正确定义dto?如何正确定义dto,以便返回对象列表?

  • 我有一个自定义的文章类型(媒体文章),它使用一些自定义字段,有一个自定义分类法(媒体文章类别)和该分类法中的14个术语。我可以使用CPT归档模板输出所有自定义帖子。 我在侧边栏中还有一个菜单,它列出了用于过滤自定义帖子的术语(我使用了一个自定义WP菜单小部件来创建列表)。 我用一个查询设置了一个自定义分类模板。根据args中放置的分类术语,我能够成功地组合或单独显示帖子。因此,如果我不需要使用过滤

  • 问题内容: 假设我有一个事件()实例,其中有许多,则需要获取属于的所有对象,其中AttendancePerson.person参加了多个事件,该事件的 相匹配,并且在上一年结束的位置。 模式减去不相关的列名: 目的是找到任何给定事件的老成员。在上一年中多次参加共享同一日历的活动的任何活动出席者都是该活动的“老会员”。 我阅读了许多相关的问题。他们都没有帮助。谢谢任何对此有帮助的人。 问题答案: 对

  • 1. 简介 分析云作为企业进行全域用户行为数据分析的数据中台,需要满足企业不同业务角色的各类差异化分析需求。 其中,对于企业深度结合业务模式的定制化需求,分析云平台提供了“自定义SQL查询”的功能,支持业务人员自行编辑复杂的 SQL 查询语言,实现对平台数据仓库中最底层的细粒度用户行为数据进行分析操作,以获取当前分析云平台既有数据模型无法覆盖的个性化分析需求的结果。 2. 使用说明 当前 sql

  • 我被一个非常琐碎的问题困扰了两天。我正在创建一个带有Restendpoint的spring boot项目。有两个实体类-Employee和Address,其中一个映射为OneToMany,一个Employee具有地址列表。我创建了一个EmployeeRepository类,该类实现了JpaRepository,用于执行与员工相关的事务。因此,需要通过地址id获取员工,因此根据我的理解,如果我们必须