JPA bidirection Relation Mapping(JPA双向关联映射)

一、bidirection Relation Mapping (1-1)

  • 应用场景:假设一个人仅有一个地址,一个地址也仅有一个人;
  • 实体类定义:Person:代表人实体; Address:代表地址实体。

        Address实体定义:

@Entity
@Table(name = "rm_address")
public class Address {
	@Id
	@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "addressPKGen")
	@SequenceGenerator(name = "addressPKGen", sequenceName = "ADDRESS_PK_GEN", allocationSize = 1)
	@Column(name = "address_id", length = 11)
	private int addressId;

	@Column(length = 512)
	private String detail;

	@OneToOne(targetEntity = Person.class, cascade = CascadeType.ALL, fetch = FetchType.LAZY, optional = false, mappedBy = "address")
	private Person person;

	public Address() {

	}

	public Address(String detail) {
		this.detail = detail;
	}

	public Address(int addressId, String detail) {
		super();
		this.addressId = addressId;
		this.detail = detail;
	}

	public int getAddressId() {
		return addressId;
	}

	public void setAddressId(int addressId) {
		this.addressId = addressId;
	}

	public String getDetail() {
		return detail;
	}

	public void setDetail(String detail) {
		this.detail = detail;
	}

	public Person getPerson() {
		return person;
	}

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

        Person实体定义:

@Entity
@Table(name = "rm_person")
public class Person {

	@Id
	@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "personPKGen")
	@SequenceGenerator(name = "personPKGen", sequenceName = "PERSON_PK_GEN", allocationSize = 1)
	@Column(name = "person_id", length = 11)
	private int personId;

	@Column(length = 256)
	private String name;

	@Column(length = 11)
	private int age;

	@OneToOne(targetEntity = Address.class, cascade = CascadeType.ALL, fetch = FetchType.LAZY, optional=false)
	@JoinColumn(name="address_id", nullable=false)
	private Address address;

	public Person() {

	}

	public int getPersonId() {
		return personId;
	}

	public void setPersonId(int personId) {
		this.personId = personId;
	}

	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;
	}

	public Address getAddress() {
		return address;
	}

	public void setAddress(Address address) {
		this.address = address;
	}
}

        在上面的实体定义中,Address和Person都有对方的引用,在Person实体中控制关联关系。在Address实体的person属性中,只采用@OneToOne修饰,并增加了MappedBy="address",说明Address不控制关联关系; 在Person实体的address属性中,采用了@OneToOne 和 @JoinColumn来修饰该属性。

        测试代码:

public class Test {

	private static final EntityManagerFactory emf = Persistence
			.createEntityManagerFactory("qs");

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		EntityManager em = emf.createEntityManager();
		
		try{
			em.getTransaction().begin();
			
			Person sun = new Person();
			sun.setName("孙悟空");
			sun.setAge(500);
			sun.setAddress(new Address("花果山福地,水帘洞洞天"));
			
			em.persist(sun);
			
			Person zhu = new Person();
			zhu.setName("猪八戒");
			zhu.setAge(380);
			zhu.setAddress(new Address("高老庄"));
			
			em.persist(zhu);
			
			em.getTransaction().commit();
			
		}finally{
			em.close();
		}
	}
}

 

二、bidirection Relation Mapping (1-N  or N-1)  

  • 应用场景:假设一个人对应多个地址,一个地址只对应一个人;
  • 实体类定义:Person:代表人实体; Address:代表地址实体。

        Person实体定义:

@Entity
@Table(name = "rm_person")
public class Person {

	@Id
	@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "personPKGen")
	@SequenceGenerator(name = "personPKGen", sequenceName = "PERSON_PK_GEN", allocationSize = 1)
	@Column(name = "person_id", length = 11)
	private int personId;

	@Column(length = 256)
	private String name;

	@Column(length = 11)
	private int age;

	@OneToMany(targetEntity=Address.class, cascade=CascadeType.ALL, fetch=FetchType.EAGER, mappedBy="person")
	private Set<Address> addresses = new HashSet<Address>();

	public Person() {

	}

	public int getPersonId() {
		return personId;
	}

	public void setPersonId(int personId) {
		this.personId = personId;
	}

	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;
	}

	public Set<Address> getAddresses() {
		return addresses;
	}

	public void setAddresses(Set<Address> addresses) {
		this.addresses = addresses;
	}
}


        Address实体的定义:

@Entity
@Table(name = "rm_address")
public class Address {
	@Id
	@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "addressPKGen")
	@SequenceGenerator(name = "addressPKGen", sequenceName = "ADDRESS_PK_GEN", allocationSize = 1)
	@Column(name = "address_id", length = 11)
	private int addressId;

	@Column(length = 512)
	private String detail;

	@ManyToOne(targetEntity = Person.class, cascade = CascadeType.ALL, fetch = FetchType.LAZY, optional = false)
	@JoinColumn(name="person_id", nullable=false)
	private Person person;

	public Address() {

	}

	public Address(String detail) {
		this.detail = detail;
	}

	public Address(int addressId, String detail) {
		super();
		this.addressId = addressId;
		this.detail = detail;
	}

	public int getAddressId() {
		return addressId;
	}

	public void setAddressId(int addressId) {
		this.addressId = addressId;
	}

	public String getDetail() {
		return detail;
	}

	public void setDetail(String detail) {
		this.detail = detail;
	}

	public Person getPerson() {
		return person;
	}

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

       在上面的实体定义中,Address和Person都有对方的引用,在多的一端Address实体中控制关联关系。在Address实体的person属性中,只采用@ManyToOne和@JoinColumn修饰; 在Person实体的address属性中,采用了@OneToMany修饰该属性,并制定了MappedBy="person",说明Person实体不控制关联关系。

测试代码:

public class Test {

	private static final EntityManagerFactory emf = Persistence
			.createEntityManagerFactory("qs");

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		EntityManager em = emf.createEntityManager();
		
		try{
			
			Address  address =	em.find(Address.class, 1);
			
			System.out.println("addressDetail: " + address.getDetail());
		
			System.out.println("PersonId: " + address.getPerson().getPersonId());
			System.out.println("PersonName: " + address.getPerson().getName());
			System.out.println("PersonAge: " + address.getPerson().getAge());
			
			/*em.getTransaction().begin();
			
			Person sun = new Person();
			sun.setName("孙悟空");
			sun.setAge(500);

			Address mountain = new Address("花果山福地,水帘洞洞天");
			Address load = new Address("取经之路");
			
			mountain.setPerson(sun);
			load.setPerson(sun);
			
			em.persist(mountain);
			em.persist(load);
			
			em.getTransaction().commit();*/
			
		}finally{
			em.close();
		}
	}
}


 

三、bidirection Relation Mapping (N-N)

  • 应用场景:假设一个人对应多个地址,一个地址也对应多个人;
  • 实体类定义:Person:代表人实体; Address:代表地址实体。

         Address实体定义:

@Entity
@Table(name = "rm_address")
public class Address {
	@Id
	@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "addressPKGen")
	@SequenceGenerator(name = "addressPKGen", sequenceName = "ADDRESS_PK_GEN", allocationSize = 1)
	@Column(name = "address_id", length = 11)
	private int addressId;

	@Column(length = 512)
	private String detail;

	@ManyToMany(targetEntity=Person.class, cascade=CascadeType.ALL, fetch=FetchType.LAZY, mappedBy="addresses")
	private Set<Person> persons = new HashSet<Person>();

	public Address() {

	}

	public Address(String detail) {
		this.detail = detail;
	}

	public Address(int addressId, String detail) {
		super();
		this.addressId = addressId;
		this.detail = detail;
	}

	public int getAddressId() {
		return addressId;
	}

	public void setAddressId(int addressId) {
		this.addressId = addressId;
	}

	public String getDetail() {
		return detail;
	}

	public void setDetail(String detail) {
		this.detail = detail;
	}

	public Set<Person> getPersons() {
		return persons;
	}

	public void setPersons(Set<Person> persons) {
		this.persons = persons;
	}

}

Person实体定义:

@Entity
@Table(name = "rm_person")
public class Person {

	@Id
	@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "personPKGen")
	@SequenceGenerator(name = "personPKGen", sequenceName = "PERSON_PK_GEN", allocationSize = 1)
	@Column(name = "person_id", length = 11)
	private int personId;

	@Column(length = 256)
	private String name;

	@Column(length = 11)
	private int age;

	@ManyToMany(targetEntity=Address.class, cascade=CascadeType.ALL, fetch=FetchType.LAZY)
	@JoinTable(
			name="rm_person2address", 
			joinColumns=@JoinColumn(name="person_id", nullable=false), 
			inverseJoinColumns=@JoinColumn(name="address_id", nullable=false))
	private Set<Address> addresses = new HashSet<Address>();

	public Person() {

	}

	public int getPersonId() {
		return personId;
	}

	public void setPersonId(int personId) {
		this.personId = personId;
	}

	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;
	}

	public Set<Address> getAddresses() {
		return addresses;
	}

	public void setAddresses(Set<Address> addresses) {
		this.addresses = addresses;
	}
}


上面2个实体中,都采用了@ManyToOne修饰,并在Person实体中采用了@JoinTable修饰,有Person端控制关联关系。

 

测试代码:

public class Test {

	private static final EntityManagerFactory emf = Persistence
			.createEntityManagerFactory("qs");

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		EntityManager em = emf.createEntityManager();
		
		try{
			em.getTransaction().begin();
			
			Address load = new Address("取经之路");
			
			Person sun = new Person();
			sun.setName("孙悟空");
			sun.setAge(500);
			sun.getAddresses().add(load);
			sun.getAddresses().add(new Address("花果山福地,水帘洞洞天"));

			Person zhu = new Person();
			zhu.setName("猪八戒");
			zhu.setAge(380);
			zhu.getAddresses().add(load);
			zhu.getAddresses().add(new Address("高老山"));
		
			em.persist(sun);
			em.persist(zhu);
			
			em.getTransaction().commit();
			
		}finally{
			em.close();
		}
		

	}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值