@OneToMany、@ManyToOne以及@ManyToMany讲解(五)

来源:互联网 发布:印象笔记导入为知笔记 编辑:程序博客网 时间:2024/04/28 22:49

一、一对多(@OneToMany
1、单向一对多模型
假设通过一个客户实体可以获得多个地址信息。
对于一对多的实体关系而言,表结构有两种设计策略,分别是外键关联和表关联。
(1) 映射策略---外键关联
在数据库中表customer和表结构address定义,如下:

01

create table customer (

02

  id int(20) not null auto_increment,

 

03

  name varchar(100),

04

  primary key(id)

 

05

)

06

 

 

07

create table address (

08

  id int(20) not null auto_increment,

 

09

  province varchar(50),

10

  city varchar(50),

 

11

  postcode varchar(50),

12

  detail varchar(50),

 

13

  customer_id int(20),

14

  primary key (id)

 

15

)

注意此时外键定义在多的一方,也就是address表中。

 此时,表customer映射为实体CustomerEO,代码如下:

1

@Entity

2

@Table(name="customer")

 

3

public class CustomerEO implements java.io.Serializable {

4

  @OneToMany(cascade={ CascadeType.ALL })

 

5

  @JoinColumn(name="customer_id")

6

  private Collection<AddressEO> addresses = new ArrayList<AddressEO>();

 

7

 ...

8

}

注释@OneToMany的定义代码如下:

1

@Target({METHOD, FIELD}) @Retention(RUNTIME)

2

public @interface OneToMany {

 

3

  Class targetEntity() default void.class;

4

  CascadeType[] cascade() default {};

 

5

  FetchType fetch() default LAZY;

6

  String mappedBy() default "";

 

7

}

使用时要注意一下几点问题: 
atargetEntity属性表示默认关联的实体类型。如果集合类中指定了具体类型了,不需要使用targetEntity.否则要指定targetEntity=AddressEO.class 
bmappedBy属性用于标记当实体之间是双向时使用。 

(2) 映射策略---表关联 
在上面address表中去掉customer_id字段,在增加一个表ref_customer_address,如下: 

1

--客户地址关系表

2

create table ref_customer_address (

 

3

  customer_id int(20) not null,

4

  address_id int(20) not null unique

 

5

)

此时表customer映射为CustomerEO实体,代码如下:

01

@Entity

02

@Table(name = "customer")

 

03

public class CustomerEO implements java.io.Serializable {

04

  ...

 

05

  @OneToMany(cascade = { CascadeType.ALL })

06

  @JoinTable(name="ref_customer_address",

 

07

           joinColumns={ @JoinColumn(name="customer_id",referencedColumnName="id")},

08

           inverseJoinColumns={@JoinColumn(name="address_id",referencedColumnName="id")})

 

09

  private Collection<AddressEO> addresses = new ArrayList<AddressEO>();

10

  ...

 

11

}

表关联@JoinTable,定义如下:

1

@Target({METHOD,FIELD})

2

public @interface JoinTable {

 

3

  String name() default "";

4

  String catalog() default "";

 

5

  String schema() default "";

6

  JoinColumn[] joinColumns() default {};

 

7

  JoinColumn[] inverseJoinColumns() default {};

8

  UniqueConstraint[] uniqueConstraints default {};

 

9

}

其中:
a、该标记和@Table相似,用于标注用于关联的表。
bname属性为连接两张表的表名。默认的表名为:表名1”+“-”+“表名2”,上面例子默认的表名为customer_address
cjoinColumns属性表示,在保存关系中的表中,所保存关联的外键字段。
dinverseJoinColumns属性与joinColumns属性类似,不过它保存的是保存关系的另一个外键字段。

(3) 默认关联
在数据库底层为两张表添加约束,如下:

1

create table customer_address (

2

  customer_id int(20) not null,

 

3

  address_id int(20) not null unique

4

)

 

5

alter table customer_address add constraint fk_ref_customer foreign key (customer_id) references customer (id);

6

 

 

7

alter table customer_address add constraint fk_ref_address foreign key (address_id) references address (id);


这样,在CustomerEO中只需要在标注@OneToMany即可!


二、多对一@ManyToOne
1
、单向多对一模型。
(1)
外键关联
配置AddressEO实体如下:

01

@Entity

02

@Table(name="address")

 

03

public class AddressEO implements java.io.Serializable {

04

     

 

05

  @ManyToOne(cascade = { CascadeType.ALL })

06

  @JoinColumn(name="customer_id")

 

07

  private CustomerEO customer;

08

     

 

09

  // ...

10

}

@ManyToOne定义如下:

1

@Target({METHOD,FIELD}) @Retention(RUNTIME)

2

public @interface ManyToOne {

 

3

  Class targetEntity() default void.class;

4

  CascadeType[] cascade() default {};

 

5

  FetchType fatch() default EAGER;

6

  boolean optional() default true;

 

7

}


(2) 默认关联
数据库脚本定义的相关字段的约束,创建外键后,直接使用@ManyToOne

三、高级一对多和多对一映射
即双向关联模型,确定了双向关联后,多的一方AddressEO不变使用@ManyToOne,CustomerEO实体修改为:

1

@Entity

2

@Table(name="customer")

 

3

public class CustomerEO {

4

     

 

5

  @OneToMany(mappedBy="customer")

6

  private Collection<AddressEO> addresses = new ArrayList<AddressEO>();

 

7

     

8

  // ...

 

9

}

其中,@OneToMany标记中的mappedBy属性的值为AddressEO实体中所引用的CustomerEO实体的属性名。 

四、多对多(@ManyToMany
和一对多类型,不在赘述。@ManyToMany标记的定义如下:

1

@Target({METHOD, FIELD}) @Retention(RUNTIME)

2

public @interface ManyToMany {

 

3

  Class targetEntity() default void.class;

4

  CascadeType[] cascade() default {};

 

5

  FetchType fecth() default LAZY;

6

  String mappedBy() default "";

 

7

}


五、最后,谈谈关于集合类的选择
在映射关系中可以使用的集合类有CollectionSetListMap,下面看下如何选择。
1、定义时使用接口,初始化使用具体的类。
Collection可以初始化为ArrayListHashSet
Set可以初始化为HashSet
List可以初始化为ArrayList
Map可以初始化为HashMap.
2、集合类的选择
Collection类是SetList的父类,在未确定使用SetList时可使用;
Set集合中对象不能重复,并且是无序的;
List集合中的对象可以有重复,并且可以有排序;
Map集合是带有keyvalue值的集合。

 

0 0