Hibernate:为每个集合分别进行sql查询

时间:2016-05-05 08:32:58

标签: java hibernate

我有一个包含联系人集合的Person类。一切正常,我得到他们的联系人列表。但是,在日志中我看到一个单独的查询来读取每个人的集合。那太糟糕了。 如何使hibernate联接以读取一个查询中的所有数据?我使用JPA。

这是人类:

@Entity
@Table(name = "tbl1")
public class PersonItem implements Serializable{
    @Id
    @Column(name="col1")
    private String guid;
    .....
    @ElementCollection(targetClass = ContactItem.class,fetch=FetchType.EAGER)
    @CollectionTable(name="tbl2",joinColumns=@JoinColumn(name="col2"))
    private List<ContactItem> contacts;
    ....
}

这是联系人类

@Embeddable
@Table(name = "tbl2")
public class ContactItem implements Serializable {

    @Column(name="col1")
    private String guid;

    @Column(name="col3")
    private String info;
}

这是我获得人员名单的方式:

Query query = em.createQuery("Select p from PersonItem p WHERE p.guid IN (:guids)");
query.setParameter("guids", guids);
List<PersonItem> list=query.getResultList();

这就是我在日志中看到的内容(我在DB中有三个人):

Hibernate: select personitem0_.col1 as col1_0_, personitem0_.col4 as col2_0_, personitem0_.col2 as col3_0_, personitem0_.col3 as col4_0_ from tbl1 personitem0_ where personitem0_.col1 in (? , ? , ?)
Hibernate: select contacts0_.col2 as col1_1_0_, contacts0_.col1 as col2_1_0_, contacts0_.col3 as col3_1_0_ from tbl2 contacts0_ where contacts0_.col2=?
Hibernate: select contacts0_.col2 as col1_1_0_, contacts0_.col1 as col2_1_0_, contacts0_.col3 as col3_1_0_ from tbl2 contacts0_ where contacts0_.col2=?
Hibernate: select contacts0_.col2 as col1_1_0_, contacts0_.col1 as col2_1_0_, contacts0_.col3 as col3_1_0_ from tbl2 contacts0_ where contacts0_.col2=?

2 个答案:

答案 0 :(得分:4)

请从更简单的映射开始。使用复数名称和列前缀。

@Entity
@Table(name = "persons")
public class Person {

    @Id
    @Column(name = "f_guid")
    private String guid;

    @OneToMany(mappedBy = "person", fetch = FetchType.EAGER)
    private List<Contact> contacts;

}

@Entity
@Table(name = "contacts")
public class Contact {

    @Id
    @Column(name = "f_guid")
    private String guid;

    @Column(name = "f_info")
    private String info;

    @ManyToOne(fetch = FetchType.LAZY)    
    @JoinColumn(name = "fk_person")
    private Person person;

}

Person通过contacts表格中的外键fk_personcontacts相关联。

更新

看起来JPQL会覆盖默认的抓取策略。您需要明确指定提取

select p from PersonItem p left join fetch p.contacts WHERE p.guid IN (:guids)

如果您有重复项,连接原因,您可以使用distinct

select distinct p from PersonItem p left join fetch p.contacts WHERE p.guid IN (:guids)

答案 1 :(得分:1)

对你的关系尝试@Fetch。 另外我建议在这种情况下使用@OneToMany关系

@OneToMany(mappedBy = "person", fetch = FetchType.EAGER)
@Fetch(FetchMode.JOIN) //You can use SUBSELECT as well
private List<ContactItem> contacts;

您可以阅读有关提取策略的更多信息here

  
      
  1. fetch-“join”=禁用延迟加载,始终加载所有集合和实体。
  2.   
  3. fetch-“select”(默认)=延迟加载所有集合和实体。
  4.   
  5. batch-size =“N”=获取“N”个集合或实体,不记录
  6.   
  7. fetch-“subselect”=将其集合分组为子选择语句。
  8.