欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  数据库

one-to-one双向关联之加载

程序员文章站 2024-04-05 09:52:00
...

关于hibernate的加载方式有两种,一种是get加载,一种是load加载,load属于延迟加载,使用了动态代理。这不是我们所关心的,我们看一看一对一双向关联在加载时有什么特点,想要观察特点,不得不看hibernate为我们生成的sql语句。 husband类与上一篇没有变化

关于hibernate的加载方式有两种,一种是get加载,一种是load加载,load属于延迟加载,使用了动态代理。这不是我们所关心的,我们看一看一对一双向关联在加载时有什么特点,想要观察特点,不得不看hibernate为我们生成的sql语句。

husband类与上一篇没有变化如下:

/**
 * 
 */
package com.maybe.test_1;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Table;

/**
 * @author MayBe
 *
 * function:
 */
@Entity
@Table(name="t_husband")
public class Husband {
	
	private Integer id;
	private String name;
	private Wife wife;
	@Id
	@GeneratedValue
	public Integer getId() {
		return id;
	}
	
	public String getName() {
		return name;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public void setName(String name) {
		this.name = name;
	}

	@OneToOne(mappedBy="husband")
	public Wife getWife() {
		return wife;
	}

	public void setWife(Wife wife) {
		this.wife = wife;
	}
	

}

wife类也没有变化:

/**
 * 
 */
package com.maybe.test_1;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.Table;

/**
 * @author MayBe
 *
 * function:
 */
@Entity
@Table(name="t_wife")
public class Wife {
	
	private Integer id;
	private String name;
	private Husband husband;
	@Id
	@GeneratedValue
	public Integer getId() {
		return id;
	}
	public String getName() {
		return name;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public void setName(String name) {
		this.name = name;
	}
	@OneToOne
	public Husband getHusband() {
		return husband;
	}
	public void setHusband(Husband husband) {
		this.husband = husband;
	}
	

}

junit测试方法如下:
@Test
	public void One_to_oneLoadTest1(){
		//一对一双向关联

		Session s = sessionFacotry.getCurrentSession();
		
		s.beginTransaction();
		
		Husband hus = (Husband)s.get(Husband.class, 2);	

                System.out.println("*****************");
				
		Wife wif = (Wife)s.get(Wife.class, 3);


		s.getTransaction().commit();
	
	}

假设我们在数据中存在一个id为2的husband,他与id为2的wife是关联的。在数据库有一个id为3的wife,她与id为3的husband是关联的,我们运行一下这个测试,输出sql语句如下:
2014-02-04 16:52:20 INFO org.hibernate.tool.hbm2ddl.SchemaUpdate:182 - HHH000228: Running hbm2ddl schema update
   2014-02-04 16:52:20 INFO org.hibernate.tool.hbm2ddl.SchemaUpdate:193 - HHH000102: Fetching database metadata
   2014-02-04 16:52:20 INFO org.hibernate.tool.hbm2ddl.SchemaUpdate:205 - HHH000396: Updating schema
   2014-02-04 16:52:21 INFO org.hibernate.tool.hbm2ddl.TableMetadata:66 - HHH000261: Table found: hibernate.dbo.t_husband
   2014-02-04 16:52:21 INFO org.hibernate.tool.hbm2ddl.TableMetadata:67 - HHH000037: Columns: [id, name]
   2014-02-04 16:52:21 INFO org.hibernate.tool.hbm2ddl.TableMetadata:69 - HHH000108: Foreign keys: []
   2014-02-04 16:52:21 INFO org.hibernate.tool.hbm2ddl.TableMetadata:70 - HHH000126: Indexes: [pk__t_husban__3213e83f0f624af8]
   2014-02-04 16:52:21 INFO org.hibernate.tool.hbm2ddl.TableMetadata:66 - HHH000261: Table found: hibernate.dbo.t_wife
   2014-02-04 16:52:21 INFO org.hibernate.tool.hbm2ddl.TableMetadata:67 - HHH000037: Columns: [id, husband_id, name]
   2014-02-04 16:52:21 INFO org.hibernate.tool.hbm2ddl.TableMetadata:69 - HHH000108: Foreign keys: [fk_fi3kodkmubgryyblf4935y4dk]
   2014-02-04 16:52:21 INFO org.hibernate.tool.hbm2ddl.TableMetadata:70 - HHH000126: Indexes: [pk__t_wife__3213e83f1332dbdc]
   2014-02-04 16:52:21 INFO org.hibernate.tool.hbm2ddl.SchemaUpdate:242 - HHH000232: Schema update complete
   Hibernate: 
    select
        husband0_.id as id1_0_0_,
        husband0_.name as name2_0_0_,
        wife1_.id as id1_1_1_,
        wife1_.husband_id as husband_3_1_1_,
        wife1_.name as name2_1_1_ 
    from
        t_husband husband0_ 
    left outer join
        t_wife wife1_ 
            on husband0_.id=wife1_.husband_id 
    where
        husband0_.id=?
*****************
Hibernate: 
    select
        wife0_.id as id1_1_0_,
        wife0_.husband_id as husband_3_1_0_,
        wife0_.name as name2_1_0_,
        husband1_.id as id1_0_1_,
        husband1_.name as name2_0_1_ 
    from
        t_wife wife0_ 
    left outer join
        t_husband husband1_ 
            on wife0_.husband_id=husband1_.id 
    where
        wife0_.id=?
Hibernate: 
    select
        wife0_.id as id1_1_1_,
        wife0_.husband_id as husband_3_1_1_,
        wife0_.name as name2_1_1_,
        husband1_.id as id1_0_0_,
        husband1_.name as name2_0_0_ 
    from
        t_wife wife0_ 
    left outer join
        t_husband husband1_ 
            on wife0_.husband_id=husband1_.id 
    where
        wife0_.husband_id=?

首先加载husband对象时会把相关联的字段全部加载出来。

但是可以看出来加载wife表的时候会执行两次查询,虽然这两次查询的内容是一样的,但是第一次是查询出的是主表的信息,第二次是为了查出从表信息,这是hibernate的默认加载策略,因为t_wife表有外键,如果加载的表有从表,他会默认加载同时夹在两个表的信息。是否加载从表信息是由fetch进行设置的。

我们把wife类one-to-one新添加一个属性

/**
 * 
 */
package com.maybe.test_1;

import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.Table;

/**
 * @author MayBe
 *
 * function:
 */
@Entity
@Table(name="t_wife")
public class Wife {
	
	private Integer id;
	private String name;
	private Husband husband;
	@Id
	@GeneratedValue
	public Integer getId() {
		return id;
	}
	public String getName() {
		return name;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public void setName(String name) {
		this.name = name;
	}
	@OneToOne(fetch=FetchType.LAZY)
	public Husband getHusband() {
		return husband;
	}
	public void setHusband(Husband husband) {
		this.husband = husband;
	}
	
}

我们把抓取方式改成懒抓取,加载输出如下所示:

2014-02-04 17:07:38 INFO org.hibernate.tool.hbm2ddl.SchemaUpdate:182 - HHH000228: Running hbm2ddl schema update
2014-02-04 17:07:38 INFO org.hibernate.tool.hbm2ddl.SchemaUpdate:193 - HHH000102: Fetching database metadata
2014-02-04 17:07:38 INFO org.hibernate.tool.hbm2ddl.SchemaUpdate:205 - HHH000396: Updating schema
2014-02-04 17:07:39 INFO org.hibernate.tool.hbm2ddl.TableMetadata:66 - HHH000261: Table found: hibernate.dbo.t_husband
2014-02-04 17:07:39 INFO org.hibernate.tool.hbm2ddl.TableMetadata:67 - HHH000037: Columns: [id, name]
2014-02-04 17:07:39 INFO org.hibernate.tool.hbm2ddl.TableMetadata:69 - HHH000108: Foreign keys: []
2014-02-04 17:07:39 INFO org.hibernate.tool.hbm2ddl.TableMetadata:70 - HHH000126: Indexes: [pk__t_husban__3213e83f0f624af8]
2014-02-04 17:07:40 INFO org.hibernate.tool.hbm2ddl.TableMetadata:66 - HHH000261: Table found: hibernate.dbo.t_wife
2014-02-04 17:07:40 INFO org.hibernate.tool.hbm2ddl.TableMetadata:67 - HHH000037: Columns: [id, husband_id, name]
2014-02-04 17:07:40 INFO org.hibernate.tool.hbm2ddl.TableMetadata:69 - HHH000108: Foreign keys: [fk_fi3kodkmubgryyblf4935y4dk]
2014-02-04 17:07:40 INFO org.hibernate.tool.hbm2ddl.TableMetadata:70 - HHH000126: Indexes: [pk__t_wife__3213e83f1332dbdc]
2014-02-04 17:07:40 INFO org.hibernate.tool.hbm2ddl.SchemaUpdate:242 - HHH000232: Schema update complete
Hibernate:
select
husband0_.id as id1_0_0_,
husband0_.name as name2_0_0_,
wife1_.id as id1_1_1_,
wife1_.husband_id as husband_3_1_1_,
wife1_.name as name2_1_1_
from
t_husband husband0_
left outer join
t_wife wife1_
on husband0_.id=wife1_.husband_id
where
husband0_.id=?
*****************
Hibernate:
select
wife0_.id as id1_1_0_,
wife0_.husband_id as husband_3_1_0_,
wife0_.name as name2_1_0_
from
t_wife wife0_
where
wife0_.id=?

这样wife类只加载自己主表的信息,不考虑从表的信息了( 当然把husband也是如此,可以自己去试试)。

hibernate默认的加载策略为eager加载,也就是急抓取,会把所关联的信息一次性全部得到,而lazy则都是在你用到从表才会去加载。

我们改变一下测试类内容:

	public void One_to_oneLoadTest1() {
		// 一对一双向关联

		Session s = sessionFacotry.getCurrentSession();

		s.beginTransaction();

		Husband hus = (Husband) s.get(Husband.class, 2);

    	

		System.out.println("*****************");
		Wife wif = (Wife) s.get(Wife.class, 3);
		

		System.out.println(wif.getHusband().getName());
		s.getTransaction().commit();

	}

输出如下:

2014-02-04 17:10:51 INFO org.hibernate.tool.hbm2ddl.SchemaUpdate:182 - HHH000228: Running hbm2ddl schema update
2014-02-04 17:10:51 INFO org.hibernate.tool.hbm2ddl.SchemaUpdate:193 - HHH000102: Fetching database metadata
2014-02-04 17:10:51 INFO org.hibernate.tool.hbm2ddl.SchemaUpdate:205 - HHH000396: Updating schema
2014-02-04 17:10:51 INFO org.hibernate.tool.hbm2ddl.TableMetadata:66 - HHH000261: Table found: hibernate.dbo.t_husband
2014-02-04 17:10:51 INFO org.hibernate.tool.hbm2ddl.TableMetadata:67 - HHH000037: Columns: [id, name]
2014-02-04 17:10:51 INFO org.hibernate.tool.hbm2ddl.TableMetadata:69 - HHH000108: Foreign keys: []
2014-02-04 17:10:51 INFO org.hibernate.tool.hbm2ddl.TableMetadata:70 - HHH000126: Indexes: [pk__t_husban__3213e83f0f624af8]
2014-02-04 17:10:51 INFO org.hibernate.tool.hbm2ddl.TableMetadata:66 - HHH000261: Table found: hibernate.dbo.t_wife
2014-02-04 17:10:51 INFO org.hibernate.tool.hbm2ddl.TableMetadata:67 - HHH000037: Columns: [id, husband_id, name]
2014-02-04 17:10:51 INFO org.hibernate.tool.hbm2ddl.TableMetadata:69 - HHH000108: Foreign keys: [fk_fi3kodkmubgryyblf4935y4dk]
2014-02-04 17:10:51 INFO org.hibernate.tool.hbm2ddl.TableMetadata:70 - HHH000126: Indexes: [pk__t_wife__3213e83f1332dbdc]
2014-02-04 17:10:51 INFO org.hibernate.tool.hbm2ddl.SchemaUpdate:242 - HHH000232: Schema update complete
Hibernate:
select
husband0_.id as id1_0_0_,
husband0_.name as name2_0_0_,
wife1_.id as id1_1_1_,
wife1_.husband_id as husband_3_1_1_,
wife1_.name as name2_1_1_
from
t_husband husband0_
left outer join
t_wife wife1_
on husband0_.id=wife1_.husband_id
where
husband0_.id=?
*****************
Hibernate:
select
wife0_.id as id1_1_0_,
wife0_.husband_id as husband_3_1_0_,
wife0_.name as name2_1_0_
from
t_wife wife0_
where
wife0_.id=?
Hibernate:
select
husband0_.id as id1_0_0_,
husband0_.name as name2_0_0_,
wife1_.id as id1_1_1_,
wife1_.husband_id as husband_3_1_1_,
wife1_.name as name2_1_1_
from
t_husband husband0_
left outer join
t_wife wife1_
on husband0_.id=wife1_.husband_id
where
husband0_.id=?
Hibernate:
select
wife0_.id as id1_1_0_,
wife0_.husband_id as husband_3_1_0_,
wife0_.name as name2_1_0_
from
t_wife wife0_
where
wife0_.husband_id=?
GossipMan

这样才会加载从表的信息,对于一些其他的语句,可能是hibernate自动生成的其他语句,但只要理解其中的思想就可以了,不要在意这些细节。