JPA查询使用计数选择多对一查询

时间:2013-04-02 15:44:50

标签: java jpa playframework-1.x

所以我正在尝试根据下面的类(稍微笨拙地)编写一个JPA查询,这将产生以下结果:

所以我有两个对象:Thing和Person。一个人可以持有对单一事物的引用。以下是类的简化版本:

public class Thing {
    @Id
    public Long id;
    public String name;
    public String description;
}

public class Person {
    @Id
    public Long id;
    public String firstname;
    public String lastname;
    @ManyToOne
    public Thing thing;
}

我正在尝试编写一个JPA查询,它将为我提供每个Thing对象的所有详细信息以及Person对象引用Thing对象的次数。请注意,Person可以为Thing赋值null。此外,任何Person对象都可能不会引用Thing对象,但仍应列出。

所以给出以下表格:

Thing Table
| id | name | description |
|  1 | thg1 | a thing     |
|  2 | thg2 | another one |
|  3 | thg3 | one more    |

Person Table
| id | firstname | lastname | thing |
|  1 | John      | Smith    |     1 |
|  2 | Simon     | Doe      |     3 |
|  3 | Anne      | Simmons  |     1 |
|  4 | Jessie    | Smith    |     1 |
|  5 | Adam      | Doe      |     3 |
|  6 | Phil      | Murray   |  null |

我最终得到的结果如下:

| id | name | description | amount |
|  1 | thg1 | a thing     |      3 |
|  2 | thg2 | another one |      2 |
|  3 | thg3 | one more    |      0 |

我将如何编写JPA查询? (如果它有所作为我正在使用Play Framework 1.2.5)

2 个答案:

答案 0 :(得分:3)

它应该是这样的:

select t.id, t.name, t.description, count(p) as amount
         from Person as p right join p.thing as t group by t.id

异常“正确加入”的原因是JPA查询需要查询类之间的映射,而您只有PersonThing之间的映射。

如果您有从ThingPerson的映射:

class Thing {
    ...
    @OneToMany
    Set<Person> persons;
}

你可以使用经典的“左连接”:

select t.id, t.name, t.description, count(p) as amount
             from Thing as t left join t.persons as p group by t.id

答案 1 :(得分:0)

好的,如果我正在编写纯JPQL并设置实体关系,那么我会这样:

public class Thing {
    @Id
    public Long id;
    public String name;
    public String description;
    @OneToMany
    public Collection<Person> personList;

}

public class Person {
    @Id
    public Long id;
    public String firstname;
    public String lastname;
}

<强>查询:

SELECT t from Thing {WHERE watever condition you may have}

迭代:

Collection<Thing> thingList = query.getResultList();

System.out.println("| id | name | description | amount |");
for(Thing thing:thingList){
System.out.format("|  %s | %s | %s    |      %s |%n", thing.getId(), thing.getName(), thing.getDescription(), thing.getPersonList().size());
}