在使用Hibernate的JPA实现时,我注意到了一个有趣的优化行为。在同一事务中,初始JPA查询的WHERE子句用于涉及初始查询结果的后续查询。
例如,person具有lastName和一组拥有的书籍。
// (1) get person by last name
Query q = entityManager.createQuery("SELECT p FROM Person p WHERE p.firstName = :lastName");
q.setParameter("lastName", "Smith");
List<Person> persons = q.getResultList();
// (2) get books owned by some arbitrary person in persons
Person person = persons.get(n);
Collection<Book> books = person.books;
(1)转换为SQL:
SELECT ... FROM Person WHERE lastName = 'Smith'
当运行(2)并访问Person的书籍时,它会生成SQL:
SELECT ... FROM Person_Book book0_ WHERE book0_.personId IN (SELECT ... FROM ... WHERE lastName = 'Smith')
以某种方式记住(1)中的WHERE子句并将其用于涉及检索到的人的后续查询(2)中。调用Hibernate中的这种行为是什么?如何配置它?
跟进:我在人的书上使用subselect。这解释了我所看到的行为。
答案 0 :(得分:1)
摘自this link:
我想要介绍的最后一种提取形式是subselect fetching。子选择提取与批量大小控制提取非常相似,我刚才描述过,但是从方程式中得出“数值复杂度”。子选择提取实际上是应用于集合样式关联的不同类型的提取策略。但是,与连接样式提取不同,子选择提取仍与惰性关联兼容。不同之处在于,如同我的同事所说的那样,次选择获取只会得到“整个射击”的匹配,而不仅仅是一批。换句话说,它使用子选择执行将主实体集的ID集传递给关联表的select off:
从所有者
中选择*从pet中选择* owner_id in(从所有者中选择id)