2013-04-02 57 views
3

所以我想编写一个基于以下班JPA查询多到一个查询(简单化了一点),将产生以下:JPA查询选择带有计数

所以,我有两个对象:事物和人物。一个人可以举一个单一的东西的参考。各阶级的这里被简化版本:

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可以具有null值。此外,Thing对象可能根本不会被任何Person对象引用,但仍应列出。

所以给出如下表:

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查询? (如果让我用播放框架1.2.5差异)

回答

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 
+0

感谢@dcernahoschi是正确的联接为我工作。我意识到关系映射并不完美,但不幸的是,它现在在应用程序中根深蒂固。也许我会考虑适当地重写它。 – gordon

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()); 
}