对 JP-QL (JPA 2.0) 中的“ElementCollection”映射字段执行“MEMBER OF”查询
Posted
技术标签:
【中文标题】对 JP-QL (JPA 2.0) 中的“ElementCollection”映射字段执行“MEMBER OF”查询【英文标题】:Execute "MEMBER OF" query against 'ElementCollection' Map fields in JP-QL (JPA 2.0) 【发布时间】:2010-12-05 14:37:20 【问题描述】:是否可以对关联数组运行“成员”查询?如果是这样,语法是什么样的?明显的解决方法是原生查询,但是对于所有的连接等,它变得非常混乱。我想测试地图的键集、值集合或条目集中是否存在对象。可能类似于以下内容:
SELECT p FROM Person p WHERE 'home' MEMBER OF p.phoneNumbers.keySet
SELECT p FROM Person p WHERE '867-5309' MEMBER OF p.phoneNumbers.values
SELECT p FROM Person p WHERE 'home' -> '867-5309' MEMBER OF p.phoneNumbers
提供者无关的代码可能要求太多; Eclipselink 支持吗?
【问题讨论】:
p.phoneNumbers 是什么类型? “MapJPQL 有一个名为index()
的函数,它对于获取@OrderColumn
列表中的索引很有用。正如您自己所说,映射也称为关联数组,映射键对应于数组索引。所以没有什么能阻止index()
返回映射条目的键。
这个查询在休眠状态下完美运行:
SELECT p FROM Person p, in (p.phoneNumbers) number
WHERE number = '867-5309' AND index(number) = 'home'
【讨论】:
key() 应该用于 Map,而不是 index() @James 我不知道key()
,但已经测试过index()
,它可以工作。【参考方案2】:
它应该可以工作:
SELECT p FROM Person p
WHERE (select count(*) from p.phoneNumbers where name='home' and value='867-5309') > 0
下一个查询对我有用:
select model from AnsOutboxMsg model
left join fetch model.updateEntity upde
left join fetch upde.update upd
left join fetch model.ansMessage msg
left join fetch msg.template msgt
left join fetch msg.ansAction act
left join fetch act.ansRule rl
left join fetch rl.app app
where (select count(*) from model.contextMap where name = 'fltClient' and value = 'XXX') > 0 and model.status = 'sent' and app.id = 'SPN_TICKETS' and msgt.name = 'Client' order by model.modifDate DESC, model.id ASC
【讨论】:
【参考方案3】:JPA(2) 规范没有为在 MEMBER OF 中使用的 Map 定义其语法(您最初指的是数组,但如果您有地图,我看不到相关性) ,因此您不能依赖任何对所有 JPA 实现都有效的语法。由于 JPQL 不支持诸如 keySet 之类的 Java 方法,因此我看不到那些可能的值。它很可能只支持检查值是否存在,例如
'867-5309' MEMBER OF p.phoneNumbers
作为参考,在 JDOQL 中,你会这样做
p.phoneNumbers.containsKey('home');
p.phoneNumbers.containsValue('867-5309');
【讨论】:
以上是关于对 JP-QL (JPA 2.0) 中的“ElementCollection”映射字段执行“MEMBER OF”查询的主要内容,如果未能解决你的问题,请参考以下文章