Hibernate的关联映射——单向1-N关联
单向1-N关联的持久化类里需要使用集合属性。因为1的一端需要访问N的一端,而N的一端将以集合(Set)形式表现。从这个意义上来看,1-N(实际上还包括N-N)和集合属性非常相似,只是此时集合里的元素是关联实体。
对于单向的1-N关联关系,只需要在1的一端增加Set类型的成员变量,该成员变量记录当前实体所有的关联实体,当然还要为这个Set类型的属性增加setter和getter方法。
为了映射1-N关联,需要使用@OneToMany注解。
1.无连接表的单向1-N关联
需要在N的一端添加外键列来维护关联关系,但由于程序此时只让1一端控制关联关系,因此直接在1的一端使用@JoinColumn修饰Set集合属性、映射外键列即可。
下面的Person实体可以关联多个Address实体。
import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.OneToMany; import javax.persistence.Table; import org.hibernate.annotations.Cascade; import org.hibernate.annotations.CascadeType; /** * 一个Person实例可以关联多个Address实例 */ @Entity @Table(name="person") public class Person { @Id @Column(name="p_id") @GeneratedValue(strategy=GenerationType.IDENTITY) private Integer id; @Column(name="p_name") private String name; @Column(name="p_age") private Integer age; //定义该Person实例所有关联的Address实体 @OneToMany(targetEntity=Address.class) //映射外键列,此处映射的外键列将会添加到关联实体对应的数据表中,
//注意并不是添加到当前的实体对应的数据表中,而是关联实体对应的数据表中 @JoinColumn(name="p_id",referencedColumnName="p_id") @Cascade(CascadeType.ALL) private Set<Address> addresses = new HashSet<>(); public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public Set<Address> getAddresses() { return addresses; } public void setAddresses(Set<Address> addresses) { this.addresses = addresses; } }
Address则不需要维护与Person类的关系,所以比较简单。
import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; @Entity @Table(name="address_inf") public class Address { @Id @Column(name="address_id") @GeneratedValue(strategy=GenerationType.IDENTITY) private Integer id; @Column(name="address_name") private String name; public Address(){ } public Address(String name){ this.name = name; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
测试效果。
import org.hibernate.Session; import org.hibernate.Transaction; import com.mytest.test1.HibernateUtil; public class Test { public static void main(String[] args) { Session session = HibernateUtil.currentSession(); Transaction tx = session.beginTransaction(); //创建一个Person对象 Person person = new Person(); //创建一个顺泰的Address对象 Address addressA = new Address("A"); //为Person对象设置值 person.setName("liujiang"); person.setAge(24); //设置Person和Address之间的关联 person.getAddresses().add(addressA); //持久化person对象 session.save(person); //创建一个瞬态的Address对象 Address addressB = new Address("B"); //持久化addressB session.persist(addressB); //修改持久化状态的person对象 person.getAddresses().add(addressB); tx.commit(); HibernateUtil.currentSession(); } }
2.有连接表的单向1-N关联
对于有连接表的单向1-N关联,同样需要使用过@OneToMany修饰代表关联实体的集合属性。除此之外,程序还应该用@JoinTable显式指定连接表。
import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.JoinTable; import javax.persistence.OneToMany; import javax.persistence.Table; @Entity @Table(name="person2") public class Person2 { @Id @Column(name="p_id") @GeneratedValue(strategy=GenerationType.IDENTITY) private Integer id; @Column(name="p_name") private String name; @Column(name="p_age") private Integer age; //定义该Person实体所有关联的Address实体 @OneToMany(targetEntity=Address.class) //映射连接表为person_address @JoinTable( name="person_address", //定义连接表中名为“p_id”的外键列,该外键列参照当前实体对应表的主键列 joinColumns=@JoinColumn( name="p_id", referencedColumnName="p_id" ), //定义连接表中名为address_id的外键列 //该外键列参照当前实体关联的实体对应表的主键列 inverseJoinColumns=@JoinColumn( name="address_id", referencedColumnName="p_id",
unique=true
) ) public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } }