Hibernate一对一关联

一对一单向外键关联

1.建Husband实体类和Wife实体类,添加Annotation注解,如下

@Entity

public class Husband {

	private int id;

	private String name;



	private Wife wife;        

	@Id

	@GeneratedValue

	public int getId() {

		return id;

	}

	public void setId(int id) {

		this.id = id;

	}

	public String getName() {

		return name;

	}

	public void setName(String name) {

		this.name = name;

	}



	@OneToOne                   //Husband和Wife是一对一的关系

	public Wife getWife() {

		return wife;

	}

	public void setWife(Wife wife) {

		this.wife = wife;

	}

}

 

@Entity

public class Wife {

	private int id;

	private String name;

	@Id

	@GeneratedValue

	public int getId() {

		return id;

	}

	public void setId(int id) {

		this.id = id;

	}

	public String getName() {

		return name;

	}

	public void setName(String name) {

		this.name = name;

	}

}

 

2.在hibernate.cfg.xml中添加mapping语句

<mapping class="com.hibernate.model.Husband"/> 

<mapping class="com.hibernate.model.Wife"/>

3.建Junit测试类

public class ORMappingTest {



	@Test

	public void test() {

		//生成表,输出建表语句

		new SchemaExport(new Configuration().configure()).create(true, true);

	}

}

程序至此结束,运行程序,在数据库中生成Husband表和Wife表,并在控制台输出建表语句。

Husband表中会自动生成属性名为“wife_id”的外键,参考表为Wife表。

如果想要使用自定义的外键属性名,可对Husband实体类的getWife方法添加Annotation注解,如下:

@OneToOne   //Husband和Wife是一对一的关系

@JoinColumn(name="wifeId")  // java默认生成的外键属性名为wife_id.设置此项后,可以任意设定其属性名,此处设置为wifeId.

public Wife getWife() {

	return wife;

	}

 

一对一双向外键关联

1.建Husband实体类和Wife实体类,添加Annotation注解

Husband类同上,只需在Wife类中增加一个Husband类型的变量,并添加@OneToOne注解即可,如下

@Entity

public class Wife {

	private int id;

	private String name;

	

	private Husband husband;   //建一个Husband类型的变量,并生成setter和getter方法 

	

	@Id

	@GeneratedValue

	public int getId() {

		return id;

	}

	public void setId(int id) {

		this.id = id;

	}

	public String getName() {

		return name;

	}

	public void setName(String name) {

		this.name = name;

	}

	

	@OneToOne(mappedBy="wife")     //"wife"指的是Husband类中的private Wife wife;

	public Husband getHusband() {

		return husband;

	}

	public void setHusband(Husband husband) {

		this.husband = husband;

	}	

}

凡是双向关联,必设mappedBy

2.在hibernate.cfg.xml中添加mapping语句----同上

3.建Junit测试类----同上

程序至此结束,运行程序,在数据库中生成Husband表和Wife表,并在控制台输出建表语句。

 

联合主键

联合主键(3种方式)



    将主键类注解为@Embeddable,并将主键(pk)的属性注解为@Id (不常用)



    将主键的属性注解为@EmbeddedId  



    将实体类注解为@IdClass(组件类.class),并将该实体类中所有属于主键的属性都注解为@Id

示例:建Wife表,属性有id,name,age。其中id和name为联合主键

1.建主键类WifePK

/*

 * 建立主键类WifePK

 * 需实现Serializable接口,此接口用于把当前类的接口进行序列化

 * 需重写equals()和hashCode()方法,以保证对象的唯一性

 *  

 **/



public class WifePK implements java.io.Serializable{

	private int id;

	private String name;

	public int getId() {

		return id;

	}

	public void setId(int id) {

		this.id = id;

	}

	public String getName() {

		return name;

	}

	public void setName(String name) {

		this.name = name;

	}

	

	@Override

	public boolean equals(Object o){

		if(o instanceof WifePK){

			WifePK pk = (WifePK) o;

			if(this.id == pk.getId() && this.name.equals(pk.getName())){

				return true;

			}

		}

		return false;

	}

	

	@Override

	public int hashCode(){

		return this.name.hashCode();

	}

}

2.建实体类Wife

第二种方式注解,@EmbeddedId

@Entity

public class Wife {

	

	private WifePK pk;    //增加WifePK类型的变量,并添加getter和setter方法

	

	private int age;

	

	@EmbeddedId              //将其注解为联合主键

	public WifePK getPk() {

		return pk;

	}

	public void setPk(WifePK pk) {

		this.pk = pk;

	}

	public int getAge() {

		return age;

	}

	public void setAge(int age) {

		this.age = age;

	}

}

第三种方式注解,@IdClass

@Entity

@IdClass(WifePK.class)   //将实体类注解为@IdClass

public class Wife {	

	private int id;

	private String name;

	private int age;



	@Id               //将该实体类中属于主键的属性注解为@Id 

	public int getId() {

		return id;

	}

	public void setId(int id) {

		this.id = id;

	}



	@Id                //将该实体类中属于主键的属性注解为@Id 

	public String getName() {

		return name;

	}

	public void setName(String name) {

		this.name = name;

	}



	public int getAge() {

		return age;

	}

	public void setAge(int age) {

		this.age = age;

	}

}

3.写Junit测试类

第二种方式注解,@EmbeddedId

public class WifeTest {

private static SessionFactory sf = null;

	

	@BeforeClass

	public static void beforeClass() {

		sf = new Configuration().configure().buildSessionFactory();

	}

	

	@AfterClass

	public static void afterClass() {

		sf.close();

	}



	@Test

	public void test() {

		

		WifePK pk = new WifePK();

		pk.setId(1);

		pk.setName("zhangsan");

		

		Wife wife = new Wife();

		wife.setPk(pk);

		wife.setAge(32);

		

		Session session = sf.getCurrentSession();

		session.beginTransaction();

		

		session.save(wife);

		

		session.getTransaction().commit();



	}

}

第三种方式注解,@IdClass,只需修改其test()方法,如下:

@Test

public void test() {

		

	Wife wife = new Wife();

	wife.setId(1);

	wife.setName("zhangsan");

	wife.setAge(32);

		

	Session session = sf.getCurrentSession();

	session.beginTransaction();

		

	session.save(wife);

		

	session.getTransaction().commit();



}

程序至此结束,运行程序,在数据库中生成Wife表,id和name为主键,并将对象wife存入Wife表。

 

联合主键关联

示例:

         建Husband表,属性有id和name

         建Wife表,属性有id,name,age。其中id和name为联合主键

         设置联合主键关联,在Husband表中生成属性名为wife_id和wife_name的外键,分别参考Wife表中的id和name

        

1.建Husband实体类、Wife实体类和WifePK主键类,添加Annotation注解

Husband类,同上

WifePK类,同上

Wife类,同“联合主键”部分第三种方式注解的Wife实体类

2.在hibernate.cfg.xml中添加mapping语句----同上

3.建Junit测试类ORMappingTest----同上

程序至此结束,运行程序,在数据库中生成Husband表和Wife表,并在控制台输出建表语句。

Husband表中会自动生成属性名为“wife_id”和“wife_name”的外键,参考表为Wife表。

如果想要使用自定义的外键属性名,可对Husband实体类的getWife方法添加Annotation注解,如下:

@OneToOne

@JoinColumns(

		{

			@JoinColumn(name="wifeId",referencedColumnName="id"),

			@JoinColumn(name="wifeName",referencedColumnName="name")

		}

)

public Wife getWife() {

	return wife;

}

组件映射

除了粗粒度的对象模型设计(一个表映射成一个持久化类)之外,还可以采用细粒度的对象模型,把一个表映射成两个或者多个类。

被细化出来的类,可以称为组件(Component)。

组件是某个实体的逻辑组成部分,它与实体的本质区别在于组件没有id,可以把组件当做值对象。

举例来说:Husband类有id、name、wifeName、wifeAge等属性,将wifeName、wifeAge从Husband实体类中拿出来,单独建一个Wife类,这个类就叫做值对象,也就是所说的组件。表现在数据库中,将只有husband一张表,有id、name、wifeName、wifeAge属性。

采用组件映射的优点:实现了对象细粒度的划分,层次更加分明,复用率高。

1.建立Husband实体类和Wife组件类,添加Annotation注解

Husband类同上,只是不需要添加@OneToOne注解,改为@Embedded注解,如下:

@Embedded

public Wife getWife() {

	return wife;

}

Wife类无需添加任何注解,如下:

public class Wife {

	

	private String wifeName;

	private int wifeAge;



	public String getWifeName() {

		return wifeName;

	}

	public void setWifeName(String wifeName) {

		this.wifeName = wifeName;

	}

	public int getWifeAge() {

		return wifeAge;

	}

	public void setWifeAge(int wifeAge) {

		this.wifeAge = wifeAge;

	}	

}

2.在hibernate.cfg.xml中添加mapping语句

只需添加Husband的mapping,Wife类不是实体类,无需添加。

3.建Junit测试类ORMappingTest----同上

程序至此结束,运行程序,在数据库中生成Husband表,并在控制台输出建表语句。

Husband表中有id、name、wifeName、wifeAge属性。

你可能感兴趣的:(Hibernate)