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 class="native"></generator>
        </id>
        
        
        <property name="name" 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 class="Phone"/>
        </set>
  
    </class>
</hibernate-mapping>
 

 

<?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 class="native"></generator>
        </id>
        
        
        <property name="num" 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 class="Phone"/>
        </set>
        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 class="Phone"/>
        </set>

 虽然lazy=true,但是因为fetch是join,运行上面的代码,sql有变化,直接一个sql 通过 left join加载出所有phone

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的方式查询子表

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值