我将分页与hibernate的spring-data-jpa和querydsl一起使用@BatchSize(size=10),并且我只用于一次往返数据库。
@BatchSize(size=10)
@Entity @Table(name = "appel_offre", catalog = "ao") public class AppelOffre implements java.io.Serializable { .... @OneToMany(fetch = FetchType.LAZY, mappedBy = "appelOffre") @BatchSize(size=10) public Set<AoActivite> getAoActivites() { return this.aoActivites; }
和:
@Entity @Table(name = "ao_activite", catalog = "ao") public class AoActivite implements java.io.Serializable { ..... @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "ID_ACTIVITE", nullable = false) @BatchSize(size=10) public Activite getActivite() { return this.activite; }
我的查询
JPAQuery query = new JPAQuery(entityManager).from(ao) .leftJoin( ao.acheteur, ach ).fetch() .leftJoin( ao.aoActivites , ao_ac ) .leftJoin( ao_ac.activite , ac ) .offset(...).limit(...).list(..);
但是在日志中有很多往返数据库的行程:
1 - round-trip ..... Hibernate: select ... from ao.ao_activite aoactivite0_ where aoactivite0_.ID_APPEL_OFFRE in (?, ?, ?, ?, ?, ?, ?, ?, ?, ?) Hibernate: select ... from ao.activite activite0_ where activite0_.ID_ACTIVITE=? Hibernate: select ... from ao.activite activite0_ where activite0_.ID_ACTIVITE=? 2 - round-trip ..... Hibernate: select ... from ao.activite activite0_ where activite0_.ID_ACTIVITE=? Hibernate: select ... from ao.activite activite0_ where activite0_.ID_ACTIVITE=? Hibernate: select ... from ao.activite activite0_ where activite0_.ID_ACTIVITE=? 3 - round-trip ..... Hibernate: select ... from ao.activite activite0_ where activite0_.ID_ACTIVITE=? Hibernate: select ... from ao.activite activite0_ where activite0_.ID_ACTIVITE=? 4 - round-trip ..... Hibernate: select ... from ao.activite activite0_ where activite0_.ID_ACTIVITE=? 5 - round-trip ..... 6 - round-trip ..... Hibernate: select ... from ao.activite activite0_ where activite0_.ID_ACTIVITE=? 7 - round-trip ...... 8 - round-trip ..... Hibernate: select ... from ao.activite activite0_ where activite0_.ID_ACTIVITE=? 9 - round-trip ..... 10 - round-trip
该@BatchSize两个有道理
@BatchSize
One-To-Many
Many-to-One
以防万一Many-To-One,我们必须在@Entity级别上应用它(在我们的Activite类映射中)
Many-To-One
@Entity
Activite
@Entity @BatchSize(size=25) @Table(name = "activite" ... public class Activite implements java.io.Serializable { ...
在doc中检查它 ( 在 下面附加小引用) :
US/html_single/#performance-fetching-batch)
… 批量获取类/实体更容易理解。考虑以下示例:在运行时,您在一个Session中加载了25个Cat实例,并且每个实例Cat都引用了其所有者Person。在Person类的映射使用了代理服务器,为lazy =“真”。如果您现在遍历所有的猫并调用getOwner()它们,默认情况下,Hibernate将执行25条SELECT语句以检索代理的所有者。您可以通过在Person映射中指定一个批处理大小来调整此行为:
…
批量获取类/实体更容易理解。考虑以下示例:在运行时,您在一个Session中加载了25个Cat实例,并且每个实例Cat都引用了其所有者Person。在Person类的映射使用了代理服务器,为lazy =“真”。如果您现在遍历所有的猫并调用getOwner()它们,默认情况下,Hibernate将执行25条SELECT语句以检索代理的所有者。您可以通过在Person映射中指定一个批处理大小来调整此行为:
Cat
Person
getOwner()
<class name="Person" batch-size="10">...</class>