在ZF2-PostgreSQL应用程序中,我想使用Doctrine2本机查询来构建分页器列表。
因此,如果选择任何自定义Doctrine / Pgsql类型,它会很有用。但对于一个查询,我会使用自定义类型的数据。
我在PostgreSQL中声明了一个名为AlertRecipient
的Doctrine 2自定义类型,如下所示:
CREATE TYPE alert_recipient AS (
email text,
status int
);
此类型用于某些表格。 clients
表中的示例:
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[]
扩展alert_recipient
以存储许多alert_recipient
条记录的列表
此类型与实体相关联,用于保湿:
class AlertRecipient
{
protected $email;
protected $status;
// ... with accessors
}
Doctrine类型注册是在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[]');
// ...
自定义类型学说适配器已编写,例如文档http://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 . ')';
}
从find()
开始,使用AlertRecipient
实体正确补充结果:string '[{"email":"john@doe.com","status":1}, {"email":"jane@doe.com","status":1}]'
从本地查询水合,结果['order_emails']在AlertRecipient
实体中没有水合:string '{"(john@doe.com, 1), (jane@doe.com, 1)"}'
然后数据没有正确补充......
感谢您的想法
修改
alertRecipient
实体中Client
财产的声明:
/* @ORM\Column(type="alert_recipient[]", nullable=true, name="alert_recipients")
* @Gedmo\Versioned
*/
protected $alertRecipients = [];
// ... with accessors
答案 0 :(得分:0)
您是否关注broadcasting?
您应该使用convertToPHPValue
和convertToDatabaseValue
这样的方法来保持水分正常工作。
您还写道:
从
正确补充了结果find()
开始,使用AlertRecipient
实体...
据我了解,AlertRecipient
是一个dbal Type
类,而不是Entity
类。
键入类(因此您的AlertRecipient
类)应该扩展Doctrine\DBAL\Types\Type
。
然后,您应该在实体定义中使用此类型标记具有正确类型属性的列:
/** @Column(type="alert_recipient") */
$alertRecipient;
由于您没有共享所有详细信息(例如您使用自定义类型的实体定义),我不确定您哪里出错,但如果您按照文档说明这一切都应该按预期工作,那么我的猜猜你会跳过其中一个步骤。