Doctrine DBAL ->execute() 和 Hydration,DB2 字段名称包括“#”
Posted
技术标签:
【中文标题】Doctrine DBAL ->execute() 和 Hydration,DB2 字段名称包括“#”【英文标题】:Doctrine DBAL ->execute() and Hydration with DB2 field names including '#' 【发布时间】:2016-09-20 17:12:15 【问题描述】:我正在尝试使用 Doctrine DBAL 实现模型/映射器类型的交互,但遇到了一些问题。我的一些列名末尾有一个“#”。更改名称不是一种选择。 $'COL1#' 语法适用于常规变量,但 php 似乎很难将其用作对象属性。
解析错误:语法错误,意外的'$',期望变量(T_VARIABLE in...
如何为字段名称中带有井号标签的表创建模型?
【问题讨论】:
问题 1:您是否配置了 Doctrine 实体?问题 2:您是否尝试使用Zend\Stdlib\Hydrator\ClassMethods
水合器来水合实体?
@ceadreak 由于这个问题,我开始使用 Doctrine 实体,但这些数据库表已有近 40 年的历史,并且几乎不存在关系。此外,我们还有不使用 PHP(其他语言但相同的表)工作的开发人员,我不能指望他们在更改数据库时记得更改实体。所以我相信实体是不可能的。至于ClassMethods
,我用它来补充水分,但我仍然必须遍历每一行。
您不能在 mysql 中创建视图并将列重命名为更友好的名称(没有#
)...? Doctrine 支持为您的模型使用视图。
【参考方案1】:
我看不出在没有实体的情况下使用 Doctrine 的意义。
如果您的数据库真的很旧(40 岁,天哪!),您应该使用数据库抽象层/框架,例如 Zend DB(抱歉您使用的是 ZF2)或 Aura(@ 987654321@)。
但如果你真的想使用 Doctrine,你应该手动创建实体,并使用魔法 setter - getter 来处理特殊字段并访问/水合你的实体。
编辑
想象你的数据库有一个表 Clients
和 2 个字段:id
和 name#1
class Client
protected $id;
protected $name1;
public function __set()
// here you can set unknown properties
// remove '#' e.g ...
public function setName1($name1)
$this->name1 = $name1;
return $this;
public function getName1()
return $this->name1;
// ... other accessors
用法:
$results = clients_query_result ...
$hydrator = new ClassMethods();
$clients = [];
foreach ($results as $result)
$client = new Client();
$clients[] = $hydrator->hydrate($result, $client);
// that's it, now you have a collection of Client objects
【讨论】:
谢谢,我使用的是 Doctrine DBAL 但不是 Doctrine ORM。我想我可以使用Zend\DB
和Zend\Db\ResultSet\HydratingResultSet
来代替,但是据我所知,这仍然会循环两次结果集。我并不是真的在问我的具体情况。我只是好奇,如果每个人在使用 hydrators 时都会循环访问他们的查询结果两次,或者是否还有其他一些我不知道的方法/技巧。循环两次似乎很愚蠢,但也许一般的概念是拥有一个模型值得额外的开销。
这取决于您的结果集...如果是对象或数组,您可以轻松使用 ClassMethods 水合器。但是对于这种情况,您不需要使用 Doctrine。不可能从实体创建架构,也不可能从架构创建出色的实体......我更新了我的答案,向您展示了实体和 ClassMethods 水合的示例。希望它会有所帮助
ClassMethods 无法处理主题标签。我必须使用Zend\Stdlib\Hydrator\ArraySerializable
并配置我的exchangeArray
和getArrayCopy()
方法,以便它们将关联从我的表名映射到我的对象属性。【参考方案2】:
您可以create views in MySQL 并将您的列重命名为在这些视图中更友好的名称(没有#
)...?像这样,您不必更改原始表,但仍然可以解决这些命名问题。
Doctrine 还为您的模型支持the use of views。
许多数据库支持在语义上映射到某些表的视图上的所有 CRUD 操作。您可以为所有有问题的表和列名创建视图以...
它们指的是不同的场景,但使用视图的相同解决方案可能会有所帮助。
据我了解,您只是在使用 Doctrine DBAL,但无论如何 here some more information 在将 MySQL 视图与教义 ORM 结合使用时,它可能会有所帮助(对您或其他人)。
【讨论】:
谢谢,这不是我最终采用的解决方案,但它仍然是解决问题的可能解决方案。这就是我将其标记为答案的原因。以上是关于Doctrine DBAL ->execute() 和 Hydration,DB2 字段名称包括“#”的主要内容,如果未能解决你的问题,请参考以下文章
工匠迁移错误“找不到类'Doctrine\\DBAL\\Driver\\PDOMySql\\Driver'”,
使用 Doctrine/DBAL 迁移数据库时如何修复未知数据库错误?
PostgreSQL 咨询锁不适用于 Doctrine 的 DBAL