你说的
我试着将收藏的“获取”策略设置为“再选择”,希望它能做到。
一个查询
对于所有书籍
您可以,但您需要访问一些属性来抛出子select
@Entity
public class Book{
private List<LocalizedString> nameList = new ArrayList<LocalizedString>();
@OneToMany(cascade=javax.persistence.CascadeType.ALL)
@org.hibernate.annotations.Fetch(org.hibernate.annotations.FetchMode.SUBSELECT)
public List<LocalizedString> getNameList() {
return this.nameList;
}
private List<LocalizedString> descriptionList = new ArrayList<LocalizedString>();
@OneToMany(cascade=javax.persistence.CascadeType.ALL)
@org.hibernate.annotations.Fetch(org.hibernate.annotations.FetchMode.SUBSELECT)
private List<LocalizedString> getDescriptionList() {
return this.descriptionList;
}
}
如下操作
public class BookRepository implements Repository {
public List<Book> getAll(BookFetchingStrategy fetchingStrategy) {
switch(fetchingStrategy) {
case BOOK_WITH_NAMES_AND_DESCRIPTIONS:
List<Book> bookList = session.createQuery("from Book").list();
// Notice empty statement in order to start each subselect
for (Book book : bookList) {
for (Name address: book.getNameList());
for (Description description: book.getDescriptionList());
}
return bookList;
}
}
public static enum BookFetchingStrategy {
BOOK_WITH_NAMES_AND_DESCRIPTIONS;
}
}
我已经做了下面的一个来填充数据库
SessionFactory sessionFactory = configuration.buildSessionFactory();
Session session = sessionFactory.openSession();
session.beginTransaction();
// Ten books
for (int i = 0; i < 10; i++) {
Book book = new Book();
book.setName(RandomStringUtils.random(13, true, false));
// For each book, Ten names and descriptions
for (int j = 0; j < 10; j++) {
Name name = new Name();
name.setSomething(RandomStringUtils.random(13, true, false));
Description description = new Description();
description.setSomething(RandomStringUtils.random(13, true, false));
book.getNameList().add(name);
book.getDescriptionList().add(description);
}
session.save(book);
}
session.getTransaction().commit();
session.close();
以及找回
session = sessionFactory.openSession();
session.beginTransaction();
List<Book> bookList = session.createQuery("from Book").list();
for (Book book : bookList) {
for (Name address: book.getNameList());
for (Description description: book.getDescriptionList());
}
session.getTransaction().commit();
session.close();
我懂了
冬眠:
select
book0_.id as id0_,
book0_.name as name0_
from
BOOK book0_
休眠:返回100行(如预期)
select
namelist0_.BOOK_ID as BOOK3_1_,
namelist0_.id as id1_,
namelist0_.id as id1_0_,
namelist0_.something as something1_0_
from
NAME namelist0_
where
namelist0_.BOOK_ID in (
select
book0_.id
from
BOOK book0_
)
休眠:返回100行(如预期)
select
descriptio0_.BOOK_ID as BOOK3_1_,
descriptio0_.id as id1_,
descriptio0_.id as id2_0_,
descriptio0_.something as something2_0_
from
DESCRIPTION descriptio0_
where
descriptio0_.BOOK_ID in (
select
book0_.id
from
BOOK book0_
)
三个select语句。无“N+1”选择问题。注意我正在使用
物业准入策略
而不是字段。记住这一点。