1、一對多(@OneToMany)
一、單向一對多模型
假設經過一個客戶實體能夠得到多個地址信息。
對於一對多的實體關係而言,表結構有兩種設計策略,分別是外鍵關聯和表關聯。
(1) 映射策略---外鍵關聯
在數據庫中表customer和表結構address定義,以下:java
create table customer ( id int(20) not null auto_increment, name varchar(100), primary key(id) ) create table address ( id int(20) not null auto_increment, province varchar(50), city varchar(50), postcode varchar(50), detail varchar(50), customer_id int(20), primary key (id) )
注意此時外鍵定義在多的一方,也就是address表中。sql
此時,表customer映射爲實體CustomerEO,代碼以下:數據庫
@Entity @Table (name="customer") public class CustomerEO implements java.io.Serializable { @OneToMany(cascade={ CascadeType.ALL }) @JoinColumn(name="customer_id") private Collection<AddressEO> addresses = new ArrayList<AddressEO>(); ... }
註釋@OneToMany的定義代碼以下: app
@Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface OneToMany { Class targetEntity() default void.class; CascadeType[] cascade() default {}; FetchType fetch() default LAZY; String mappedBy() default ""; }
使用時要注意一下幾點問題:
post
a、targetEntity屬性表示默認關聯的實體類型。若是集合類中指定了具體類型了,不須要使用targetEntity.不然要指定targetEntity=AddressEO.class。
b、mappedBy屬性用於標記當實體之間是雙向時使用。
(2) 映射策略---表關聯
在上面address表中去掉customer_id字段,在增長一個表ref_customer_address,以下:
fetch
--客戶地址關係表 create table ref_customer_address ( customer_id int(20) not null, address_id int(20) not null unique )
此時表customer映射爲CustomerEO實體,代碼以下:
spa
@Entity @Table(name = "customer") public class CustomerEO implements java.io.Serializable { ... @OneToMany(cascade = { CascadeType.ALL }) @JoinTable(name="ref_customer_address", joinColumns={ @JoinColumn(name="customer_id",referencedColumnName="id")}, inverseJoinColumns={@JoinColumn(name="address_id",referencedColumnName="id")}) private Collection<AddressEO> addresses = new ArrayList<AddressEO>(); ... }
表關聯@JoinTable,定義以下:
設計
@Target({METHOD,FIELD}) public @interface JoinTable { String name() default ""; String catalog() default ""; String schema() default ""; JoinColumn[] joinColumns() default {}; JoinColumn[] inverseJoinColumns() default {}; UniqueConstraint[] uniqueConstraints default {}; }
其中:
a、該標記和@Table類似,用於標註用於關聯的表。
b、name屬性爲鏈接兩張表的表名。默認的表名爲:「表名1」+「-」+「表名2」,上面例子默認的表名爲customer_address。
c、joinColumns屬性表示,在保存關係中的表中,所保存關聯的外鍵字段。
d、inverseJoinColumns屬性與joinColumns屬性相似,不過它保存的是保存關係的另外一個外鍵字段。
(3) 默認關聯
在數據庫底層爲兩張表添加約束,以下:
code
create table customer_address ( customer_id int(20) not null, address_id int(20) not null unique ) alter table customer_address add constraint fk_ref_customer foreign key (customer_id) references customer (id); alter table customer_address add constraint fk_ref_address foreign key (address_id) references address (id);
這樣,在CustomerEO中只須要在標註@OneToMany便可!
orm
2、多對一@ManyToOne
一、單向多對一模型。
(1) 外鍵關聯
配置AddressEO實體以下:
@Entity @Table(name="address") public class AddressEO implements java.io.Serializable { @ManyToOne(cascade = { CascadeType.ALL }) @JoinColumn(name="customer_id") private CustomerEO customer; // ... }
@ManyToOne定義以下:
@Target({METHOD,FIELD}) @Retention(RUNTIME) public @interface ManyToOne { Class targetEntity() default void.class; CascadeType[] cascade() default {}; FetchType fatch() default EAGER; boolean optional() default true; }
(2) 默認關聯
數據庫腳本定義的相關字段的約束,建立外鍵後,直接使用@ManyToOne
3、高級一對多和多對一映射
即雙向關聯模型,肯定了雙向關聯後,多的一方AddressEO不變使用@ManyToOne,而CustomerEO實體修改成:
@Entity @Table(name="customer") public class CustomerEO { @OneToMany(mappedBy="customer") private Collection<AddressEO> addresses = new ArrayList<AddressEO>(); // ... }
其中,@OneToMany標記中的mappedBy屬性的值爲AddressEO實體中所引用的CustomerEO實體的屬性名。
4、多對多(@ManyToMany)
和一對多類型,不在贅述。@ManyToMany標記的定義以下:
@Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface ManyToMany { Class targetEntity() default void.class; CascadeType[] cascade() default {}; FetchType fecth() default LAZY; String mappedBy() default ""; }
5、最後,談談關於集合類的選擇
在映射關係中可使用的集合類有Collection、Set、List和Map,下面看下如何選擇。
一、定義時使用接口,初始化使用具體的類。
如Collection能夠初始化爲ArrayList或HashSet;
Set能夠初始化爲HashSet;
List能夠初始化爲ArrayList;
Map能夠初始化爲HashMap.
二、集合類的選擇
Collection類是Set和List的父類,在未肯定使用Set或List時可以使用;
Set集合中對象不能重複,而且是無序的;
List集合中的對象能夠有重複,而且能夠有排序;
Map集合是帶有key和value值的集合。