Hibernate 1+n问题
<?xml version="1.0"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><hibernate-mapping package="test.hibernate"> <class name="Person" table="Person" dynamic-update="true"> <id name="id" column="id" type="integer" unsaved-value="null"> <generator column="name" type="string"></property> <property name="age" column="age" type="integer"></property> <set name="phones" inverse="true"> <key column="person_id" not-null="false"></key> <one-to-many name="code"><?xml version="1.0"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><hibernate-mapping package="test.hibernate"> <class name="Phone" table="Phone" dynamic-update="true"> <id name="id" column="id" type="integer" unsaved-value="null"> <generator column="num" type="string"></property> </class></hibernate-mapping>?
默认情况下lazy=true,fetch=select
<set name="phones" inverse="true"> <key column="person_id" not-null="false"></key> <one-to-many name="code"> Session session = HibernateUtil.getSessionFactory().getCurrentSession(); session.beginTransaction(); Person p = (Person)session.get(Person.class, 1); session.getTransaction().commit();
?结果:
Hibernate: select person0_.id as id0_0_, person0_.name as name0_0_, person0_.age as age0_0_ from Person person0_ where person0_.id=?
?
如果改为:
<set name="phones" inverse="true" fetch="join"> <key column="person_id" not-null="false"></key> <one-to-many name="code">Hibernate: select person0_.id as id0_1_, person0_.name as name0_1_, person0_.age as age0_1_, phones1_.person_id as person3_3_, phones1_.id as id3_, phones1_.id as id1_0_, phones1_.num as num1_0_ from Person person0_ left outer join Phone phones1_ on person0_.id=phones1_.person_id where person0_.id=??
以上只是针对根据ID查询时候的情况,当用list()方法查询多个记录的时候,虽然配置了join,但是lazy依然有效
并没有通过join的方式查询phone
Hibernate: select person0_.id as id0_, person0_.name as name0_, person0_.age as age0_ from Person person0_?
再来,lazy=false,fetch="join",但是这次我们修改查询语句
Session session = HibernateUtil.getSessionFactory().getCurrentSession(); session.beginTransaction(); Person p = (Person)session.createQuery("from Person").list().get(0); session.getTransaction().commit();
?出现了著名的N+1问题,先查出所有person,再挨个person查phone
Hibernate: select person0_.id as id0_, person0_.name as name0_, person0_.age as age0_ from Person person0_Hibernate: select phones0_.person_id as person3_1_, phones0_.id as id1_, phones0_.id as id1_0_, phones0_.num as num1_0_ from Phone phones0_ where phones0_.person_id=?Hibernate: select phones0_.person_id as person3_1_, phones0_.id as id1_, phones0_.id as id1_0_, phones0_.num as num1_0_ from Phone phones0_ where phones0_.person_id=?
?
?
总结:
1、在get和load查询的时候,不管lazy是什么值,只要fetch=join,就会用left join的方式查询子表
?
?
?