在 SQL 查询中混合参数的 Doctrine Criteria

Posted

技术标签:

【中文标题】在 SQL 查询中混合参数的 Doctrine Criteria【英文标题】:Doctrine Criteria mixing up parameters in SQL query 【发布时间】:2015-11-27 18:16:11 【问题描述】:

除非先急切地加载关联,否则有一个似乎正在查询混合参数的原则标准。

设置非常简单。我有四个实体:User、Business、UserBusiness 和 UserBusinessMeta。

每个用户可以属于一个或多个企业。每个 UserBusiness 还可以具有给定业务的元键/值列表。所以,

用户:

id:3

业务:

id:2

用户业务:

user_id: 3 business_id:2

UserBusinessMeta(在 db 中还有一个对 user_id、business_id、key 的唯一约束):

user_id: 3 business_id:2 键:'foo' 值:'bar'

在我的 UserBusiness 实体中,我有一个名为 getFoo 的方法,它的条件如下所示:

$criteria = Criteria::create()
->where(Criteria::expr()->eq('key', 'foo'))
->setMaxResults(1);

return $this->meta->matching($criteria)->first();

由于某种原因,当为该条件创建 SQL 时,它会在设置参数时反转 business_id 和 user_id 的值,以便寻找 business_id 为 3 和 user_id 为 2!

SELECT 
t0.user_id AS user_id_1, 
t0.business_id AS business_id_2, 
t0.`key` AS key_3, 
t0.`value` AS value_4, 
t0.id AS id_5,
t0.user_id AS user_id_6, 
t0.business_id AS business_id_7 
FROM user_business_meta t0 
WHERE (t0.`key` = ? AND t0.user_id = ? AND t0.business_id = ?) LIMIT 1

array (size=3)
  0 => string 'foo' (length=11)
  1 => int 2
  2 => int 3
array (size=3)
  0 => string 'string' (length=6)
  1 => string 'integer' (length=7)
  2 => string 'integer' (length=7)

但是,如果我将 UserBusinessMeta 关联提取设置为 EAGER,则变量会正确加载到内存中,并且上述条件(不必使用 SQL)会返回正确的结果。

我使用 XML 映射,其中并没有什么特别之处。列和字段的名称以及关联都是正确的:

Business -> 一对多 UserBusiness UserBusiness -> 一对多 UserBusinessMeta

这里的关联映射是:

 <one-to-many target-entity="UserBusinessMeta" mapped-by="UserBusiness" field="meta" orphan-removal="true">
            <cascade>
                <cascade-persist/>
                <cascade-remove/>
            </cascade>
        </one-to-many>

并且 user_id 和 business_id 列是映射的:

    <id name="businessId" column="business_id" type="integer" />
    <id name="userId" column="user_id" type="integer" />

在 UserBusinessMeta 中,返回到 UserBusiness 的多对一关联定义如下:

<many-to-one target-entity="UserBusiness" field="UserBusiness" inversed-by="meta">
        <join-columns>
            <join-column name="user_id" referenced-column-name="user_id" />
            <join-column name="business_id" referenced-column-name="business_id" />
        </join-columns>
    </many-to-one>

最后,UserBusinessMeta 实体也有 business_id 和 user_id 两列,映射如下:

    <field name="userId" column="user_id" type="integer" />
    <field name="businessId" type="integer" column="business_id" />

【问题讨论】:

【参考方案1】:

事实证明,问题是由于 UserBusiness 实体中有两个 ID,其中一个需要标记为关联键。以下更新修复了它:

    <id name="business" column="business_id" type="integer" association-key="true" />

【讨论】:

以上是关于在 SQL 查询中混合参数的 Doctrine Criteria的主要内容,如果未能解决你的问题,请参考以下文章

使用 Laravel Eloquent 和命名绑定的 SQL 查询:混合命名参数和位置参数

如何在 SQL Server 的 Doctrine 2 中更改 DQL 查询中的 LockMode

Doctrine2 “Like” SQL 查询和“Class true 不存在”错误

用于标量查询的 Doctrine 返回数组数组

如何从 Doctrine sql 查询中映射列名?

Doctrine DBAL 可以与 ORM Query Builder 混合使用吗?