12、JPA中的一对一双向关联


IDCard.java

package cn.itcast.bean;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToOne;

@Entity
public class IDCard {
	private Integer id;
	private String cardNo;
	private Person person;

	public IDCard() {
	}

	public IDCard(String cardNo) {
		this.cardNo = cardNo;
	}

	@Id
	@GeneratedValue
	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	@Column(length = 18,nullable=false)
	public String getCardNo() {
		return cardNo;
	}

	public void setCardNo(String cardNo) {
		this.cardNo = cardNo;
	}

	@OneToOne(mappedBy = "idCard", cascade = { CascadeType.PERSIST,
			CascadeType.MERGE, CascadeType.REFRESH } /*,optional = false*/)
	public Person getPerson() {
		return person;
	}
	/*
	mappedBy:如何把IDCard指定为关系被维护端? 就是通过这属性。使用了这属性的类,就是关系被维护端。被维护端没有权力去更新外键字段。
	
	cascade:
		CascadeType.REMOVE:删除身份证,需要把这个人干掉吗? 不用,所以这个属性不设。
		CascadeType.PERSIST:一出生就有身份证号。
		CascadeType.MERGE:在游离状态的时候,修改了身份证号码,需要对人员的信息进行修改么?如果有这种业务需求,就设上去。
		CascadeType.REFRESH:重新获取idCard的数据的时候,需不需要获取person的数据呢?
	这些级联的定义,一定是根据你们的业务需求来定的。用不用是根据你的业务来决定的,业务需要就用,业务不需要就不用。
	optional:是否可选,是否允许为null?反映在业务上,就是有身份证,是否一定要有这个人呢?
	因為在Person里已经指定了idCard是必须要存在的,外键由person表维护,那么这里这个属性就是可选的的。设不设置这个person属性都行。那么在这里option这属性就可以不再进行设置了,不设置不对我们的数据构成任何影响,person可有可无不对关系(外键)存在影响。
	外键由Person的option属性决定,就算你设置了这属性,其实它也不看你这属性。在设外键字段是否允许为空的时候,也不看这属性,而是看关系维护端的设定。
	fetch:加载行为默认为立刻记载,凭one。
	*/

	public void setPerson(Person person) {
		this.person = person;
	}
}

 
Person.java 

package cn.itcast.bean;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;

@Entity
public class Person {
	private Integer id;
	private String name;
	private IDCard idCard;

	public Person() {
	}

	@Id
	@GeneratedValue
	// 采用数据库Id自增长方式来生成主键值。
	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	@Column(length = 10, nullable = false)
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	@OneToOne(optional = false, cascade = CascadeType.ALL)
	@JoinColumn(name = "idCard_id")
	public IDCard getIdCard() {
		return idCard;
	}

	public void setIdCard(IDCard idCard) {
		this.idCard = idCard;
	}

	public Person(String name) {
		this.name = name;
	}
}

 


OneToOneTest.java 

package junit.test;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

import org.junit.BeforeClass;
import org.junit.Test;

import cn.itcast.bean.IDCard;
import cn.itcast.bean.Person;

public class OneToOneTest {

	@BeforeClass
	public static void setUpBeforeClass() throws Exception {
	}

	@Test
	public void save() {
		EntityManagerFactory factory = Persistence
				.createEntityManagerFactory("itcast");
		EntityManager em = factory.createEntityManager();
		em.getTransaction().begin();

		Person person = new Person("老张");	// person是关系维护端。
		person.setIdCard(new IDCard("1112222"));	// 通过person把idCard放进去,这关系就由person来维护了。
		em.persist(person);	// 先保存idCard,得到保存记录的id,用id作为外键的值,再保存person。因为person表里的外键值是idcard表里面的主键,只有先生成主键值才有外键值。

		em.getTransaction().commit();
		em.close();
		factory.close();
	}

}

 
   谁是关系维护端,谁就负责外键字段的更新。
   Person是关系维护端,IDCard是关系被维护端,怎么维护更新呢?往Person里面设置idCard,这样就相当于把关系建立起来了;如果通过IDCard设置person的话,那么这种关系是建立不起来的,因为IDCard是关系被维护端

idcard表结构,看图: 
 
12、JPA中的一对一双向关联

 

person表结构,看图:


12、JPA中的一对一双向关联
 
 

你可能感兴趣的:(数据结构,bean,jpa,JUnit)