1. @OneToMany

@OneToMany 是屬性或方法級別的註解,用於定義源實體目標實體是一對多的關係。html

參數 類型 描述
targetEntity Class 源實體關聯的目標實體類型,默認是該成員屬性對應的集合類型的泛型的參數化類型。
mappedBy String 用在雙向關聯中。若是關係是雙向的,則需定義此參數(與 @JoinColumn 互斥,若是標註了 @JoinColumn 註解,不須要再定義此參數)。
cascade CascadeType[] 定義源實體和關聯的目標實體間的級聯關係。當對源實體進行操做時,是否對關聯的目標實體也作相同的操做。默認沒有級聯操做。該參數的可選值有:
CascadeType.PERSIST(級聯新建)
CascadeType.REMOVE(級聯刪除)
CascadeType.REFRESH(級聯刷新)
CascadeType.MERGE(級聯更新)
CascadeType.ALL(包含以上四項)
fetch FetchType 定義關聯的目標實體的數據的加載方式。
可選值:
FetchType.LAZY(延遲加載,默認)
FetchType.EAGER(當即加載)
延遲加載:只有在第一次訪問源實體關聯的目標實體的時候纔去加載。
當即加載:在加載源實體數據的時候同時去加載好關聯的目標實體的數據。
orphanRemoval boolean 源實體關聯的目標實體被斷開(如給該屬性賦予另一個實例,或該屬性的值被設爲 null。被斷開的實例稱爲孤值,由於已經找不到任何一個實例與之發生關聯)時,是否自動刪除斷開的實例(在數據庫中表現爲刪除表示該實例的行記錄),默認爲 false。
可參考:orphanRemoval 與 CascadeType.REMOVE 的區別

1.1 一對多外鍵關聯

       
       
       
       
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
       
       
       
       
@Entity(name = "user")
public class User implements Serializable {
@Id
@GeneratedValue
private Long id;
private String username;
private String password;
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
private Set<Address> addresses;
// getters and setters
}
       
       
       
       
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
       
       
       
       
@Entity(name = "address")
public class Address implements Serializable {
@Id
@GeneratedValue
private Long id;
private String name;
private String province;
private String city;
private String area;
private String detail;
// getters and setters
}

產生的 DDL 語句(MySQL):java

       
       
       
       
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
       
       
       
       
CREATE TABLE `user` (
`id` bigint( 20) NOT NULL AUTO_INCREMENT,
`password` varchar( 255) DEFAULT NULL,
`username` varchar( 255) DEFAULT NULL,
PRIMARY KEY ( `id`)
) ENGINE= InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `address` (
`id` bigint( 20) NOT NULL AUTO_INCREMENT,
`area` varchar( 255) DEFAULT NULL,
`city` varchar( 255) DEFAULT NULL,
`detail` varchar( 255) DEFAULT NULL,
`name` varchar( 255) DEFAULT NULL,
`province` varchar( 255) DEFAULT NULL,
PRIMARY KEY ( `id`)
) ENGINE= InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `user_addresses` (
`user_id` bigint( 20) NOT NULL,
`addresses_id` bigint( 20) NOT NULL,
PRIMARY KEY ( `user_id`, `addresses_id`),
UNIQUE KEY `UK_i5lp1fvgfvsplfqwu4ovwpnxs` ( `addresses_id`),
CONSTRAINT `FKfm6x520mag23hvgr1oshaut8b` FOREIGN KEY ( `user_id`) REFERENCES `user` ( `id`),
CONSTRAINT `FKth1icmttmhhorb9wiarm73i06` FOREIGN KEY ( `addresses_id`) REFERENCES `address` ( `id`)
) ENGINE= InnoDB DEFAULT CHARSET=utf8;

Hibernate @OneToMany 默認會產生一張中間表,如上例的 user_addresses 表。爲了不這種狀況,你能夠在一的一方使用 @JoinColumn 註解:git

       
       
       
       
1
2
3
       
       
       
       
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "user_id")
private Set<Address> addresses;

產生的 DDL 語句(MySQL):github

       
       
       
       
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
       
       
       
       
CREATE TABLE `user` (
`id` bigint( 20) NOT NULL AUTO_INCREMENT,
`password` varchar( 255) DEFAULT NULL,
`username` varchar( 255) DEFAULT NULL,
PRIMARY KEY ( `id`)
) ENGINE= InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `address` (
`id` bigint( 20) NOT NULL AUTO_INCREMENT,
`area` varchar( 255) DEFAULT NULL,
`city` varchar( 255) DEFAULT NULL,
`detail` varchar( 255) DEFAULT NULL,
`name` varchar( 255) DEFAULT NULL,
`province` varchar( 255) DEFAULT NULL,
`user_id` bigint( 20) DEFAULT NULL,
PRIMARY KEY ( `id`),
KEY `FKda8tuywtf0gb6sedwk7la1pgi` ( `user_id`),
CONSTRAINT `FKda8tuywtf0gb6sedwk7la1pgi` FOREIGN KEY ( `user_id`) REFERENCES `user` ( `id`)
) ENGINE= InnoDB DEFAULT CHARSET=utf8;

這樣一來,多的一方經過外鍵直接與一的一方發生關聯,不須要中間表。sql

2. @ManyToOne

@ManyToOne 是屬性或方法級別的註解,用於定義源實體目標實體是多對一的關係。數據庫

參數 類型 描述
targetEntity Class 源實體關聯的目標實體類型,默認是該成員屬性對應的類型,所以該參數一般能夠缺省。
cascade CascadeType[] 定義源實體和關聯的目標實體間的級聯關係。當對源實體進行操做時,是否對關聯的目標實體也作相同的操做。默認沒有級聯操做。該參數的可選值有:
CascadeType.PERSIST(級聯新建)
CascadeType.REMOVE(級聯刪除)
CascadeType.REFRESH(級聯刷新)
CascadeType.MERGE(級聯更新)
CascadeType.ALL(包含以上四項)
fetch FetchType 定義關聯的目標實體的數據的加載方式。
可選值:
FetchType.LAZY(延遲加載)
FetchType.EAGER(當即加載,默認)
延遲加載:只有在第一次訪問源實體關聯的目標實體的時候纔去加載。
當即加載:在加載源實體數據的時候同時去加載好關聯的目標實體的數據。
optional boolean 源實體關聯的目標實體是否容許爲 null,默認爲 true。

2.1 多對一外鍵關聯

       
       
       
       
1
2
3
4
5
6
7
8
9
10
11
12
13
14
       
       
       
       
@Entity(name = "user")
public class User implements Serializable {
@Id
@GeneratedValue
private Long id;
private String username;
private String password;
// getters and setters
}
       
       
       
       
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
       
       
       
       
@Entity(name = "address")
public class Address implements Serializable {
@Id
@GeneratedValue
private Long id;
private String name;
private String province;
private String city;
private String area;
private String detail;
@ManyToOne(optional = false)
private User user;
// getters and setters
}

產生的 DDL 語句(MySQL):app

       
       
       
       
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
       
       
       
       
CREATE TABLE `user` (
`id` bigint( 20) NOT NULL AUTO_INCREMENT,
`password` varchar( 255) DEFAULT NULL,
`username` varchar( 255) DEFAULT NULL,
PRIMARY KEY ( `id`)
) ENGINE= InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `address` (
`id` bigint( 20) NOT NULL AUTO_INCREMENT,
`area` varchar( 255) DEFAULT NULL,
`city` varchar( 255) DEFAULT NULL,
`detail` varchar( 255) DEFAULT NULL,
`name` varchar( 255) DEFAULT NULL,
`province` varchar( 255) DEFAULT NULL,
`user_id` bigint( 20) NOT NULL,
PRIMARY KEY ( `id`),
KEY `FKda8tuywtf0gb6sedwk7la1pgi` ( `user_id`),
CONSTRAINT `FKda8tuywtf0gb6sedwk7la1pgi` FOREIGN KEY ( `user_id`) REFERENCES `user` ( `id`)
) ENGINE= InnoDB DEFAULT CHARSET=utf8;

3. @OneToMany & @ManyToOne

一對多 & 多對一雙向外鍵關聯示例:post

       
       
       
       
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
       
       
       
       
@Entity(name = "user")
public class User implements Serializable {
@Id
@GeneratedValue
private Long id;
private String username;
private String password;
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "user_id")
private Set<Address> addresses;
// getters and setters
}
       
       
       
       
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
       
       
       
       
@Entity(name = "address")
public class Address implements Serializable {
@Id
@GeneratedValue
private Long id;
private String name;
private String province;
private String city;
private String area;
private String detail;
@ManyToOne(optional = false)
private User user;
// getters and setters
}

產生的 DDL 語句(MySQL):fetch

       
       
       
       
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
       
       
       
       
CREATE TABLE `user` (
`id` bigint( 20) NOT NULL AUTO_INCREMENT,
`password` varchar( 255) DEFAULT NULL,
`username` varchar( 255) DEFAULT NULL,
PRIMARY KEY ( `id`)
) ENGINE= InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `address` (
`id` bigint( 20) NOT NULL AUTO_INCREMENT,
`area` varchar( 255) DEFAULT NULL,
`city` varchar( 255) DEFAULT NULL,
`detail` varchar( 255) DEFAULT NULL,
`name` varchar( 255) DEFAULT NULL,
`province` varchar( 255) DEFAULT NULL,
`user_id` bigint( 20) NOT NULL,
PRIMARY KEY ( `id`),
KEY `FKda8tuywtf0gb6sedwk7la1pgi` ( `user_id`),
CONSTRAINT `FKda8tuywtf0gb6sedwk7la1pgi` FOREIGN KEY ( `user_id`) REFERENCES `user` ( `id`)
) ENGINE= InnoDB DEFAULT CHARSET=utf8;
原文地址:http://fanlychie.github.io/post/jpa-one-to-many-many-to-one-annotation.html