一、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();
}
}
}