Hibernate中的字段映射中的Fetch有两种方式:EAGER和LAZY
Eager:全部抓取
Lazy:延迟抓取
如果在字段中声明为Eager,那么在取得当前Bean时,同时会抓取Bean中的关联Bean值。即数据库查询多次。反之Lazy则在之后抓取提交查询。
比如,有如下声明为Eager的User Bean:
@OneToMany(mappedBy="user", cascade=CascadeType.ALL, fetch=FetchType.EAGER)
private Set<UserCard> cards;
此时使用Join查询时,将会同时把User bean下的cards均一同查询出来:
// ----------------------------------------------------
// Left join
// ----------------------------------------------------
String hql = "SELECT U FROM User U LEFT JOIN U.cards C WHERE U.userName=:userName AND C.cardID=:cardID";
Query query = session.createQuery(hql);
query.setLong("cardID", 1);
query.setString("userName", "Robin");
List<User> users = query.list();
for (User user : users) {
System.out.println("User ID:" + user.getUserID()
+ "\tUser name:" + user.getUserName());
}
输出的SQL和查询结果:
如果把Eager修改为Lazy:
@OneToMany(mappedBy="user", cascade=CascadeType.ALL, fetch=FetchType.LAZY)
private Set<UserCard> cards;
查询:
// ----------------------------------------------------
// Left join
// ----------------------------------------------------
String hql = "SELECT U FROM User U LEFT JOIN U.cards C WHERE U.userName=:userName AND C.cardID=:cardID";
Query query = session.createQuery(hql);
query.setLong("cardID", 1);
query.setString("userName", "Robin");
List<User> users = query.list();
for (User user : users) {
System.out.println("User ID:" + user.getUserID()
+ "\tUser name:" + user.getUserName());
}
输出的SQL和查询结果:
当然,大多数情况下,bean的设计都应该为Lazy。
因为如果真要同步查询得到关联对象bean的值,可以在hql中加入FETCH关键字即可完成。
Fetch参考例子:http://www.cnblogs.com/HD/p/3957926.html
使用FETCH,如上查询hql可以写为:
String hql = "SELECT U FROM User U LEFT FETCH JOIN U.cards C WHERE U.userName=:userName AND C.cardID=:cardID";
上面是转载其他前辈的资料,在本人的项目中,曾经发现实体类a里已经有了实体类B的id,但是总是获取不到该实体,后来发现是映射时设置了lazy,导致延迟加载,是在session中获取,但是此时session里是没有该实体的,所以改成了mager来从内存中获取。