天天看點

JPA 一對多、多對一注解

1. @OneToMany

@OneToMany

是屬性或方法級别的注解,用于定義源實體與目标實體是一對多的關系。

參數 類型 描述
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 一對多外鍵關聯

1234567891011121314151617      
@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
    }      
1234567891011121314151617181920      
@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):

12345678910111213141516171819202122232425      
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 注解:

123      
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "user_id")
private Set<Address> addresses;      
12345678910111213141516171819      
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;      

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

2. @ManyToOne

@ManyToOne

是屬性或方法級别的注解,用于定義源實體與目标實體是多對一的關系。

源實體關聯的目标實體類型,預設是該成員屬性對應的類型,是以該參數通常可以預設。

FetchType.LAZY(延遲加載)

FetchType.EAGER(立即加載,預設)

optional 源實體關聯的目标實體是否允許為 null,預設為 true。

2.1 多對一外鍵關聯

1234567891011121314      
@Entity(name = "user")
public class User implements Serializable {        @Id
    @GeneratedValue
    private Long id;        private String username;        private String password;        // getters and setters
    }      
1234567891011121314151617181920212223      
@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
    }      
12345678910111213141516171819      
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

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

123456789101112131415161718      
@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
    }      
1234567891011121314151617181920212223      
@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
    }      
12345678910111213141516171819      
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