在单元测试类中进行基于外键的双向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);
} }
注意在上面的保存顺序:
执行结果:
出现了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获取的是“类”的时候,没有出现错误,只返回一个代理对象,但是进行进一步的获取属性的时候就会抛出“懒加载”异常,原因就是在获取属性的时候是要进行实例化的。