在单元测试类中进行基于外键的双向1-1关联关系

 

******************************************************************************************************************************************************************

 

在单元测试类中进行基于外键的双向1-1关联关系;

 

映射文件;

 

Customer.hbm.xml

 

<?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="qau.edu.ren">

 

    <class name="Customer" table="t_customer">

 

       <id name="id" column="c_id">

           <generator class="native"/>

       </id>

 

       <property name="name" column="c_name" />

 

 

       <many-to-one name="order" class="Order" column="o_id"/>

 

    </class>

</hibernate-mapping>

 

 

 

Order.hbm.xml

 

<?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="qau.edu.ren">

 

    <class name="Order" table="t_order">

   

       <id name="id" column="o_id">

           <generator class="native" />

       </id>

 

       <property name="name" column="o_name" />

       <property name="date" column="date" />

 

       <one-to-one name="cus" class="Customer" />

      

    </class>

 

</hibernate-mapping>

 

 

上面的映射文件说明是在Customer中加入了外键。

 

测试类:

 

package qau.edu.ren;

 

import java.util.Date;

 

import org.hibernate.Session;

import org.hibernate.Transaction;

import org.hibernate.cfg.Configuration;

import org.junit.After;

import org.junit.Before;

import org.junit.Test;

 

 

 

public class hibernateTest {

 

    private Session session;

   

    private Transaction tr ;

   

    @Before

    public void init(){

      

//     获取session;

      

       session = new Configuration().configure().buildSessionFactory().openSession();

      

//     开始事务;

      

       tr = session.beginTransaction();

      

    }

   

   

    @After

    public void detroy(){

      

//     提交事务;

      

       tr.commit();

      

//     关闭Session;

      

       session.close();

    }

   

   

   

   

//      测试基于外键的1-1关联关系;

   

    @Test

    public void Testsave(){

   

//     实例化对象;

      

       Customer cus = new Customer();

      

       cus.setName("Cus-AA");

      

       Order order = new Order();

      

       order.setName("Order-AA");

       order.setDate(new Date());

      

       cus.setOrder(order);

      

       order.setCus(cus);

      

//     保存对象;

      

       session.save(cus);

      session.save(order);

     

    }

}

 

注意在上面的保存顺序:

 

执行结果:

 

Hibernate:

    insert

    into

        t_customer

        (c_name, o_id)

    values

        (?, ?)

Hibernate:

    insert

    into

        t_order

        (o_name, date)

    values

        (?, ?)

Hibernate:

    update

        t_customer

    set

        c_name=?,

        o_id=?

    where

        c_id=?

 

 

 

 

 

出现了update语句,这是和以前的单向 n-1关系的问题相同的,就是先保存带有外键的对象时,会出现update,因为里面的外键对应着关联的对象没有插入。所以为了减少 update 语句,提高效率,应该先插入没有外键的一端。

 

进行双向1-1的查询操作;

 

代码(部分)

 

//  测试获取对象;

   

    @Test

    public void TestGet(){

      

//     获取Customer对象;

      

       Customer cus = (Customer)session.get(Customer.class, 1);

      

//      只是单纯的查Customer对象的属性;

      

       System.out.println("Customer中的name属性:" + cus.getName());

      

//     通过查Customer对象,进而查Order对象;

      

       System.out.println("Order中的name属性:" + cus.getOrder().getName());

      

      

    }

 

执行结果:

 

Hibernate:

    insert

    into

        t_order

        (o_name, date)

    values

        (?, ?)

Hibernate:

    insert

    into

        t_customer

        (c_name, o_id)

    values

        (?, ?)

Hibernate:

    select

        customer0_.c_id as c1_4_0_,

        customer0_.c_name as c2_4_0_,

        customer0_.o_id as o3_4_0_

    from

        t_customer customer0_

    where

        customer0_.c_id=?

Customer中的name属性:Cus-AA

Hibernate:

    select

        order0_.o_id as o1_5_1_,

        order0_.o_name as o2_5_1_,

        order0_.date as date5_1_,

        customer1_.c_id as c1_4_0_,

        customer1_.c_name as c2_4_0_,

        customer1_.o_id as o3_4_0_

    from

        t_order order0_

    left outer join

        t_customer customer1_

            on order0_.o_id=customer1_.c_id

    where

        order0_.o_id=?

Order中的name属性:Order-AA

 

 

总结:

 

当进行只是进行查询Customer中的name属性的时候,并没有进行Order的查询和输出,尽管这是在双向的关联关系之下,这就是“懒加载”。在默认的情况之下,是执行懒加载。

 

单元测试类中测试:

 

代码(部分):

 

//  测试懒加载;

    @Test

    public void TestLazy(){

      

//     获取Customer对象;

      

       Customer cus = (Customer)session.get(Customer.class, 1);

      

       session.close();

      

       System.out.println(cus.getOrder().getClass());

      

}

 

执行结果:

 

Hibernate:

    select

        customer0_.c_id as c1_0_0_,

        customer0_.c_name as c2_0_0_,

        customer0_.o_id as o3_0_0_

    from

        t_customer customer0_

    where

        customer0_.c_id=?

class qau.edu.ren.Order_$$_javassist_0

 

 

 

代码(部分);

 

//  测试懒加载;

    @Test

    public void TestLazy(){

      

//     获取Customer对象;

      

       Customer cus = (Customer)session.get(Customer.class, 1);

      

       session.close();

      

       System.out.println(cus.getOrder().getName());

      

    }

  

 

 

执行是出现的错误:

org.hibernate.LazyInitializationException: could not initialize proxy - no Session

 

 

比较上面的两种测试和出现的结果,可以知道;但只是通过Customer查询Order获取的是“类”的时候,没有出现错误,只返回一个代理对象,但是进行进一步的获取属性的时候就会抛出“懒加载”异常,原因就是在获取属性的时候是要进行实例化的。

       

posted @ 2014-11-08 22:17  时光 说:  阅读(196)  评论(0编辑  收藏  举报