码迷,mamicode.com
首页 > Web开发 > 详细

Hibernate四 关联关系之双向关联

时间:2016-08-01 19:36:41      阅读:248      评论:0      收藏:0      [点我收藏+]

标签:

双向关联
一 双向1--N关联
1.无连接表的双向1--N关联
N的一端需要使用@ManyToOne注解来修饰代表关联实体的属性,1的一端需要使用@OneToMany注解来修饰代表关联实体的属性。
双向关联应该由N的一端来控制关联关系,因此在使用@OneToMany注解时指定mappedBy属性。一旦为@OneToMany,@ManyToMany指定了该属性,则表明当前实体不能控制关联关系,一旦当前实体放弃控制关联关系后,hibernate就不允许使用@JoinColumn或@JoinTable修饰代表关联实体的属性了。
Person.java
@Entity
@Table(name="person_info")
public class Person {
    @Id
    @Column(name="person_id")
    @GeneratedValue(strategy=GenerationType.AUTO)
    private Integer id;
    private String name;
    private int age;
 
    @OneToMany(targetEntity=Address.class,mappedBy="person")
    private Set<Address> addresses=new HashSet<>();
    ...
}
Address.java
@Entity
@Table(name="address_info")
public class Address {
    @Id
    @Column(name="address_id")
    @GeneratedValue(strategy=GenerationType.AUTO)
    private int addressId;
    private String adressDetail;
    @ManyToOne(targetEntity=Person.class)
    @JoinColumn(name="person_id",referencedColumnName="person_id",nullable=false)
    private Person person;
    ...
}
测试:
public class myTest {
    public static void main(String[] args) {
        Configuration config=new Configuration().configure();
        SessionFactory factory=config.buildSessionFactory();
        Session session=factory.openSession();
        Transaction tx=session.beginTransaction();
        Person p=new Person();
        p.setName("lyy");p.setAge(22);
        session.save(p);   //持久化person对象
        Address a=new Address("北京");
        a.setPerson(p);    //设置person和address之间的关联关系
        session.persist(a); //持久化address对象
        Address a2=new Address("南京");
        a2.setPerson(p);
        session.persist(a2);
        tx.commit();
        session.close();
    }
}
注意:最好先持久化Person对象或者该Person对象已经处于持久化状态,因为程序希望持久化Address对象时,Hibernate可以为Address的外键属性分配值。也就是说,向address_info数据表插入记录时,该记录的外键列已指定了值,着表明它参照的主表记录已存在。
不要通过Person对象来设置关联关系,因为在Person映射注解中指定了@mappedBy属性
2.有连接表的双向1--N关联
只要在N的一端使用@JoinTable显式指定连接表即可
Address.java
@Entity
@Table(name="address_info")
public class Address {
    @Id
    @Column(name="address_id")
    @GeneratedValue(strategy=GenerationType.AUTO)
    private int addressId;
    private String adressDetail;
    @ManyToOne(targetEntity=Person.class)
    @JoinTable(name="person_address",
    joinColumns=@JoinColumn(name="address_id",referencedColumnName="address_id"),
    inverseJoinColumns=@JoinColumn(name="person_id",referencedColumnName="person_id"))
    private Person person;
    ...
}
如果程序希望Person实体也可以控制关联关系,则可以将Person.java修改为:
@Entity
@Table(name="person_info")
public class Person {
    @Id
    @Column(name="person_id")
    @GeneratedValue(strategy=GenerationType.AUTO)
    private Integer id;
    private String name;
    private int age;
 
    @OneToMany(targetEntity=Address.class)
    @JoinTable(name="person_address",
    joinColumns=@JoinColumn(name="person_id",referencedColumnName="person_id"),
    inverseJoinColumns=@JoinColumn(name="address_id",referencedColumnName="address_id",unique=true))
    private Set<Address> addresses=new HashSet<>();
    ...
}
二 双向N--N关联
两端都需要使用Set集合属性,双向N--N关联只能采用连接表来建立两个实体间的关联关系
Person.java
@Entity
@Table(name="person_info")
public class Person {
    @Id
    @Column(name="person_id")
    @GeneratedValue(strategy=GenerationType.AUTO)
    private Integer id;
    private String name;
    private int age;
 
    @OneToMany(targetEntity=Address.class)
    @JoinTable(name="person_address",
    joinColumns=@JoinColumn(name="person_id",referencedColumnName="person_id"),
    inverseJoinColumns=@JoinColumn(name="address_id",referencedColumnName="address_id",unique=true))
    private Set<Address> addresses=new HashSet<>();
    ...
}
Address.java
@Entity
@Table(name="address_info")
public class Address {
    @Id
    @Column(name="address_id")
    @GeneratedValue(strategy=GenerationType.AUTO)
    private int addressId;
    private String adressDetail;
    @ManyToOne(targetEntity=Person.class)
    @JoinTable(name="person_address",
    joinColumns=@JoinColumn(name="address_id",referencedColumnName="address_id"),
    inverseJoinColumns=@JoinColumn(name="person_id",referencedColumnName="person_id"))
    private Person person;
    ...
}
三 双向1--1关联
两端都要使用@OneToOne注解进行映射,外键可以存放在任意一端,即通过@JoinColumn注解来映射外键列。一旦选择其中的一端来增加外键,该表即变为从表,另一个表则为主表。
双向1--1关联的主表对应的实体,也不应该用于控制关联关系,因此要用mappedBy属性
1.基于外键的双向1--1关联
Person.java
@Entity
@Table(name="person_info")
public class Person {
    @Id
    @Column(name="person_id")
    @GeneratedValue(strategy=GenerationType.AUTO)
    private Integer id;
    private String name;
    private int age;
 
    @OneToOne(targetEntity=Address.class,mappedBy="person")
    private Address address;
    ...
}
Address.java
@Entity
@Table(name="address_info")
public class Address {
    @Id
    @Column(name="address_id")
    @GeneratedValue(strategy=GenerationType.AUTO)
    private int addressId;
    private String adressDetail;
    @OneToOne(targetEntity=Person.class)
    @JoinColumn(name="person_id",referencedColumnName="person_id",unique=true)
    ...
}
测试:
public class myTest {
    public static void main(String[] args) {
        Configuration config=new Configuration().configure();
        SessionFactory factory=config.buildSessionFactory();
        Session session=factory.openSession();
        Transaction tx=session.beginTransaction();
        Person p=new Person("lu",23);
        Address a=new Address("nanjing");
        p.setAddress(a);
        session.save(p); session.save(a);
        tx.commit();
        session.close();
    }
}
 
 

Hibernate四 关联关系之双向关联

标签:

原文地址:http://www.cnblogs.com/lyy-2016/p/5726916.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!