//代码片5
SessionFactory sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();
Session session = sessionFactory.getCurrentSession();
session.beginTransaction();
Dream d=new Dream();
d.setDescription("marry glt");
Person p=new Person();
p.setName("dlf");
d.setPerson(p);
session.save(d);
session.save(p);
session.getTransaction().commit();
session = sessionFactory.getCurrentSession();
session.beginTransaction();
Dream dream=(Dream) session.get(Dream.class, 1);
System.out.println(dream.getPerson().getName()+" ddddd");
session.getTransaction().commit();
对应代码5而言,get dream的时候发的sql语句为
select
dream0_.id as id0_1_,
dream0_.description as descript2_0_1_,
dream0_.personId as personId0_1_,
person1_.id as id1_0_,
person1_.myname as myname1_0_
from
Dream dream0_
left outer join
Person person1_
on dream0_.personId=person1_.id
where
dream0_.id=?
换言之,get dream的时候,我们也获得了对应的person。
有3个问题
1 执行代码5的时候,dream的manytoone的cascade已经去掉了。
2 如果把Dream dream=(Dream) session.get(Dream.class, 1);与之前保存对象的语句放到一个session里,发的sql语句竟然是update。但是,System.out.println(dream.getPerson().getName()+" ddddd");依然能输入person的name。
我们能得出规律
在多对一,一对多的情况下,当我们读取多的一方时,默认也会读取一的一方。(这个规律与cascade无关)
反过来,如果我读一的一方呢,会不会也自动读出多的一方呢?
我们看代码
//代码6
public void testGetPerson() {
Session s = sessionFactory.getCurrentSession();
s.beginTransaction();
Person p = (Person)s.get(Person.class, 2);
s.getTransaction().commit();
} 这个时候它发的sql语句是:
select
person0_.id as id1_0_,
person0_.myname as myname1_0_
from
Person person0_
where
person0_.id=? 并没有去主动获得person对应的dream。
那如果我想获得dream呢?
hibernate的管理关系中还有一个参数叫fetch。它管的就是在读取某个对象时,是否需要读取与之相关的另一个对象。
通过查阅api文档,我们知道fetch的取值是fetchtype型的。而fetchtype是个Enum类型的。


这个两个值是什么意思?
猜一猜,我们大概都是知道,eager就是主动获取关联对象的数据,lazy就是不获取么。
我只能说,大概是对的。
我们看代码
在Person里面修改OneToMany的属性。
@OneToMany(mappedBy="person",fetch=FetchType.EAGER)
public Set
getDreams() {
return dreams;
}
此时再运行代码6,发的sql语句就是:
select
person0_.id as id1_1_,
person0_.myname as myname1_1_,
dreams1_.personId as personId3_,
dreams1_.id as id3_,
dreams1_.id as id0_0_,
dreams1_.description as descript2_0_0_,
dreams1_.personId as personId0_0_
from
Person person0_
left outer join
Dream dreams1_
on person0_.id=dreams1_.personId
where
person0_.id=? 我们就能知道,如果想在取一的时候同时取多的一方,就在一的一方上加上fetch=feachType.eager。
那么根据前面的代码,我们就能推测出来
在默认情况下
一的那一方的fetch是lazy
多的那一方的fetch是eager
用eager修饰关联关系:hibernate会发关联的sql
用lazy修饰关联关系:hibernate不会 主动发关联sql
注意,我上面说的是 用lazy修饰关联关系:hibernate不会发主动发关联的sql
为什么说主动呢?看看下面的代码
我们改一改代码6
//代码7
public void testGetPerson() {
Session s = sessionFactory.getCurrentSession();
s.beginTransaction();
Person p = (Person)s.get(Person.class, 2);
System.out.println(p.getDreams().size());
s.getTransaction().commit();
} 此时不设置person的fetch值。(保持默认的lazy)
此时发的sql语句是:
Hibernate:
select
person0_.id as id1_0_,
person0_.myname as myname1_0_
from
Person person0_
where
person0_.id=?
Hibernate:
select
dreams0_.personId as personId1_,
dreams0_.id as id1_,
dreams0_.id as id0_0_,
dreams0_.description as descript2_0_0_,
dreams0_.personI