映射实体Bean的关联关系之一对多(One-to-many)

在属性级使用 @OneToMany注解可定义一对多关联.一对多关联可以是双向关联.

 

2.2.5.3.2.1. 双向(Bidirectional)

 

在EJB3规范中多对一这端几乎总是双向关联中的主体(owner)端, 而一对多这端的关联注解为@OneToMany( mappedBy=... )

@Entity

public class Troop {

@OneToMany(mappedBy="troop")

public Set getSoldiers() { ...}

@Entity

public class Soldier {

@ManyToOne

 @JoinColumn(name="troop_fk")

public Troop getTroop() { ...}

Troop 通过troop 属性和Soldier建立了一对多的双向关联. 在mappedBy端不必也不能再定义任何物理映射

对于一对多的双向映射,如果要一对多这一端维护关联关系, 你需要删除mappedBy元素并将多对一这端的 @JoinColumn的insertable和updatable设置为false. 很明显,这种方案不会得到什么明显的优化,而且还会增加一些附加的UPDATE语句.

@Entity

public class Troop {

@OneToMany

@JoinColumn(name="troop_fk") //we need to duplicate the physical information

public Set getSoldiers() { ...}

@Entity

public class Soldier {

@ManyToOne

@JoinColumn(name="troop_fk", insertable=false, updatable=false)

 public Troop getTroop() { ...}

 

2.2.5.3.2.2. 单向(Unidirectional)

 

通过在被拥有的实体端(owned entity)增加一个外键列来实现一对多单向关联是很少见的,也是不推荐的. 我们强烈建议通过一个联接表(join table)来实现这种关联(下一节会对此进行解释). 可以通过@JoinColumn注解来描述这种单向关联关系.

@Entity

public class Customer implements Serializable {

@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER)

 @JoinColumn(name="CUST_ID")

public Set getTickets() { ...}

@Entity

public class Ticket implements Serializable { ... //no bidir}

Customer 通过 CUST_ID列和Ticket 建立了单向关联关系.

 

2.2.5.3.2.3. 通过关联表处理单向关联

 

通过联接表处理单向一对多关联是首选方式.这种关联通过@JoinTable注解来进行描述.

@Entity

public class Trainer {

@OneToMany

@JoinTable( name="TrainedMonkeys", joinColumns = @JoinColumn( name="trainer_id"), inverseJoinColumns = @JoinColumn( name="monkey_id") )

public Set getTrainedMonkeys() { ...}

@Entity

public class Monkey { ... //no bidir}

上面这个例子中,Trainer通过 TrainedMonkeys表和 Monkey 建立了单向关联. 其中外键trainer_id关联到Trainer (joinColumns), 而外键monkey_id关联到 Monkey(inversejoinColumns).

 

2.2.5.3.2.4. 默认处理机制

 

通过联接表来建立单向一对多关联不需要描述任何物理映射. 表名由以下三个部分组成:主表(owner table)表名+下划线+从表(the other side table)表名. 指向主表的外键名:主表表名+下划线+主表主键列名指向从表的外键名:主表所对应实体的属性名+下划线+从表主键列名 指向从表的外键定义为唯一约束,用来表示一对多的关联关系.

@Entity

public class Trainer {

@OneToMany

public Set getTrainedTigers() { ...}

@Entity

public class Tiger { ... //no bidir}

上面这个例子中,TrainerTiger 通过联接表 Trainer_Tiger建立单向关联关系, 其中外键trainer_id关联到Trainer (主表表名, _(下划线), trainer id), 而外键trainedTigers_id关联到Tiger (属性名称, _(下划线), Tiger表的主键列名).

 

 
posted on 2015-03-14 18:20  swek  阅读(267)  评论(0)    收藏  举报