标签:数据库 源码 hibernate session manytoone
本篇博客是之前博客hibernate关联对象的增删改查------查 的后继,本篇代码的设定都在前文已经写好,因此读这篇之前,请先移步上一篇博客
//代码片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();
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=?
//代码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。
@OneToMany(mappedBy="person",fetch=FetchType.EAGER) public Set<Dream> 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。
//代码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)
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_.personId as personId0_0_ from Dream dreams0_ where dreams0_.personId=?此时我们可以得到一个结论,如果在session里,我们只是获得"一"的那一方,hibernate默认不会去取多的那一方;但是如果在session里,访问了获得的"一"里面"多"的那一方数据(就是访问了person里面的dream)。就会发关联sql。
//代码8 public void testGetPerson() { testSavePerson(); Session s = sessionFactory.getCurrentSession(); s.beginTransaction(); Person p = (Person)s.get(Person.class, 2); s.getTransaction().commit(); System.out.println(p.getDreams().size()); }就是把获得多的那一方数据的代码放到了session的外面。
Hibernate: 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=? 2 //dream的size是2可是如果我把fetch=FetchType.eager去掉,在运行代码8,就会报错:
<span style="color:#FF0000;">failed to lazily initialize a collection of role: com.bjsxt.hibernate.Person.dreams, no session or session was closed</span>说的很清楚,session已经关闭了。
//代码9 public void testGetPerson() { testSavePerson(); Session s = sessionFactory.getCurrentSession(); s.beginTransaction(); Person p = (Person)s.get(Person.class, 2); s.getTransaction().commit(); System.out.println(p.getDreams().size()); s.getTransaction().commit(); }此时的person的fetch还是默认的lazy。
关于取对象这部分,hibernate还是比较麻烦的,我认为最好的方法就是保持默认的情况,一旦有了问题再查api文档,或其他的资料。
那既然这样,我为什么还要写这篇博客呢?反正最好的方法就是保持默认情况嘛。
因为:
世之奇伟、瑰怪、非常之观,常在于险远,而人之所罕至焉,故非有志者不能至也。
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:数据库 源码 hibernate session manytoone
原文地址:http://blog.csdn.net/dlf123321/article/details/46845725