七、关联映射

关联映射

1.单向N-1关联

2.单向1-1关联

3.单向1-N关联

(1)单向1-N关联与集合属性相似,只是在1-N关联时集合中的元素为关联实体;

(2)使用注解@OneToMany;

(3)无连接表的单向1-N关联

示例:

1的一端Person3:

@Entity
@Table(name="person_inf_4")
public class Person3 {
    @Id @Column(name="person_id")
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Integer id;
    private String name;
    private Integer age;
    
    @OneToMany(targetEntity=Address3.class)
    @JoinColumn(name="person_id",referencedColumnName="person_id")
    private Set<Address3> 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<Address3> getAddresses() {
        return addresses;
    }
    public void setAddresses(Set<Address3> addresses) {
        this.addresses = addresses;
    }
}

 

 

 

N的一段Address3:

@Entity
@Table(name="address_inf_4")
public class Address3 {
    @Id @Column(name="address_id")
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Integer addressId;
    private String addressDetail;
    public Address3(){
        
    }
    public Address3(String addressDetail){
        this.addressDetail = addressDetail;
    }
    public Integer getAddressId() {
        return addressId;
    }
    public void setAddressId(Integer addressId) {
        this.addressId = addressId;
    }
    public String getAddressDetail() {
        return addressDetail;
    }
    public void setAddressDetail(String addressDetail) {
        this.addressDetail = addressDetail;
    }
    
}

 

 

 

测试:

public class Test {
    public static void main(String[] args) {
        Configuration conf = new Configuration().configure();
        ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()
            .applySettings(conf.getProperties()).build();
        SessionFactory sessionFactory = conf.buildSessionFactory(serviceRegistry);
        
        Session session = sessionFactory.openSession();
        Transaction t = session.beginTransaction();
        
        //创建一个Person对象
        Person3 p = new Person3();
        //创建一个瞬态的Address对象
        Address3 address = new Address3("地址1");
        //必须先持久化address
        session.persist(address);    //与save()区别:无返回值
        
        //设置p的属性
        p.setName("name1");
        p.setAge(18);
        //设置p和address之间的关联关系
        p.getAddresses().add(address);
        
        //持久化p对象
        session.persist(p);
        
        //创建一个瞬态的Address
        Address3 address2 = new Address3("地址2");
        //持久化address2对象
        session.persist(address2);
        
        p.getAddresses().add(address2);
        t.commit();
        session.close();
        sessionFactory.close();
    }
}

(4)有连接表的单向1-N关联

  有连接表的单向1-N关联除了使用@OneToMany以外,还要使用@JoinTable显式指定连接表。

  对于采用连接表的单向1-N关联关系,由于采用了连接表维护1-N关系,两个实体对应的数据表都无须添加外键列,所以不存在主表和从表的关系,程序可以向先持久化那个实体就先持久化那个实体。无论先持久化哪个实体都不会引发性能问题。

示例:

Person4:

@Entity
@Table(name="person_inf_5")
public class Person4 {
    @Id @Column(name="person_id")
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Integer id;
    private String name;
    private Integer age;
    //定义该Person实体所有关联的Address实体
    @OneToMany(targetEntity=Address4.class)
    //映射连接表为person_address
    @JoinTable(name="person_address",
        //定义链接表中名为person_id的外键列,该外键列参照当前实体对应表的主键列
        joinColumns=@JoinColumn(
                name="person_id",
                referencedColumnName="person_id"
                ),
        //定义连接表中名为address_id的外键列
        //该外键列参照当前实体的关联实体对应表的主键列
        inverseJoinColumns=@JoinColumn(
                name="address_id",
                referencedColumnName="address_id",
                unique=true
                )
            )
    private Set<Address4> 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<Address4> getAddresses() {
        return addresses;
    }
    public void setAddresses(Set<Address4> addresses) {
        this.addresses = addresses;
    }
}

 

 

 

Address4:

@Entity
@Table(name="address_inf_5")
public class Address4 {
    @Id @Column(name="address_id")
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Integer addressId;
    private String addressDetail;
    public Address4(){
        
    }
    public Address4(String addressDetail){
        this.addressDetail = addressDetail;
    }
    public Integer getAddressId() {
        return addressId;
    }
    public void setAddressId(Integer addressId) {
        this.addressId = addressId;
    }
    public String getAddressDetail() {
        return addressDetail;
    }
    public void setAddressDetail(String addressDetail) {
        this.addressDetail = addressDetail;
    }
    
}

 

 

 

测试:

public class Test4 {
    public static void main(String[] args) {
        Configuration conf = new Configuration().configure();
        ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()
            .applySettings(conf.getProperties()).build();
        
        SessionFactory sf = conf.buildSessionFactory(serviceRegistry);
        Session session = sf.openSession();
        Transaction t = session.beginTransaction();
        
        Address4 a = new Address4("地址1");
        Address4 a2 = new Address4("地址2");
        Address4 a3 = new Address4("地址3");
        
        session.persist(a);
        session.persist(a2);
        session.persist(a3);
        
        Person4 p = new Person4();
        p.setAge(18);
        p.setName("test1");
        p.getAddresses().add(a);
        p.getAddresses().add(a2);
        p.getAddresses().add(a3);
        session.save(p);

        
        t.commit();
        session.close();
        sf.close();
    }
}

4.单向N-N关联

(1)单向N-N关联需要连接表,与使用连接表的1-N关联类似,只不过在管理关系的一端配置inverseJoinColumns参数时没有unique=true这一项,就成为了单向的N-N关联;

(2)示例:

Person(管理关联关系):

@Entity
@Table(name="person_inf_1")
public class Person {
    @Id    @Column(name="person_id")
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Integer id;
    private String name;
    private Integer age;
    @ManyToMany(targetEntity=Address.class)
    @JoinTable(
        name="person_address",
        joinColumns=@JoinColumn(
                name="person_id",
                referencedColumnName="person_id"
        ),
        inverseJoinColumns=@JoinColumn(
                name="address_id",
                referencedColumnName="address_id"
        )
    )
    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:

@Entity
@Table(name="address_inf_1")
public class Address {
    @Id @Column(name="address_id")
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Integer id;
    private String addressDetail;
    public Address(){
        
    }
    public Address(String addressDetail){
        this.addressDetail = addressDetail;
    }
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getAddressDetail() {
        return addressDetail;
    }
    public void setAddressDetail(String addressDetail) {
        this.addressDetail = addressDetail;
    }
}

 

5.双向1-N关联

6.双向N-N关联

7.双向1-1关联

8.组件属性包含的关联实体

9.基于复合主键的关联关系

10.复合主键的成员属性为关联实体

11.持久化的传播性

posted @ 2017-08-03 16:44  丶theDawn  阅读(200)  评论(0编辑  收藏  举报