当前位置:  开发笔记 > 编程语言 > 正文

JPA条件API查询子类属性

如何解决《JPA条件API查询子类属性》经验,为你挑选了1个好方法。

我想执行一个匹配特定子类属性的查询,所以我正在尝试使用treat().

在这个例子中我想要:

名称以"a"开头的
所有科目,或所有科目,即姓名以"a"开头的人

private List q1()
{
    CriteriaBuilder b = em.getCriteriaBuilder();

    CriteriaQuery q = b.createQuery(Subject.class);
    Root r = q.from(Subject.class);
    q.select(r);
    q.distinct(true);
    q.where(
        b.or(
            b.like(r.get(Subject_.name), "a%"),
            b.like(b.treat(r, Person.class).get(Person_.lastName), "a%")));

    return em.createQuery(q).getResultList();
}

显然,Person扩展Subject,Subject是抽象的,继承是SINGLE_TABLE,Subject@DiscriminatorOptions(force = true)其他原因 (非进水).

但生成的SQL是这样的:

select distinct subject0_.ID as ID2_71_, subject0_.CODE as CODE3_71_, ...
from SUBJECT subject0_ 
where subject0_.DTYPE='Person' and (subject0_.name like 'a%' or subject0_.lastName like 'a%')

虽然我期待:

select distinct subject0_.ID as ID2_71_, subject0_.CODE as CODE3_71_, ...
from SUBJECT subject0_ 
where subject0_.name like 'a%' or (subject0_.DTYPE='Person' and subject0_.lastName like 'a%')

有没有办法使用条件构建器生成预期的查询?

注意

使用另一个 -q.from(Person.class)

使用子查询 - q.subquery(Person.class)

lastName字段移动到Subject

使用本机查询

使用实体图

是不可接受的.

我对可以在WHERE子句中直接声明和使用的东西感兴趣(仅从CriteriaBuilder和/或单个Root生成,就像treat()子句一样),如果它确实存在的话.



1> Michele Mari..:

解决方案是,使用Hibernate并在此特定场景中,非常简单:

private List q1()
{
    CriteriaBuilder b = em.getCriteriaBuilder();

    CriteriaQuery q = b.createQuery(Subject.class);
    Root r = q.from(Subject.class);
    q.select(r);
    q.distinct(true);
    q.where(
        b.or(
            b.like(r.get(Subject_.name), "a%"),
            b.and(
                b.equal(r.type(), Person.class),
                b.like(((Root) (Root) r).get(Person_.lastName), "a%"))));

    return em.createQuery(q).getResultList();
}

注意双重转换,它避免了编译错误,并允许在同一个表上执行查询子句.这会产生:

select distinct subject0_.ID as ID2_71_, subject0_.CODE as CODE3_71_, ...
from SUBJECT subject0_ 
where subject0_.DTYPE in ('Office', 'Team', 'Role', 'Person', ...) 
    and (subject0_.name like 'a%' 
        or subject0_.DTYPE='Person' and (subject0_.lastName like 'a%'))

无需更改模型或其他任何内容.

推荐阅读
雨天是最美
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有