Spring工程中,創建實體對象時,可以通過JPA的@Entity標識實體與數據庫表的對應關系,@Column標識數據庫字段。其中還有標識兩個實體間關系的注解:@OneToOne、@OneToMany、@ManyToOne和@ManyToMany,分別標識一對一、一對多、多對一和多對多。在此,簡單記錄下@OneToOne和@OneToMany的使用。其中還會涉及注解@JoinColumn,其修飾的字段為關系維護字段。
@OneToOne
@OneToOne與@JoinColumn結合使用,表示會在源實體(Source Entity,即聲明該注解的實體類中創建外鍵,進行級聯),以Book和BookDetail為例。
Book類,會在book表中創建book_detail外鍵:
@Entity @Table(name = "book") @DynamicInsert(true) public class Book implements Serializable{ private static final long serialVersionUID = 1L; @Id @Column(name = "id") @GeneratedValue(strategy = GenerationType.IDENTITY) private long id; @Column(name = "name") private String name; @OneToOne(cascade = CascadeType.ALL) @JoinColumn(name = "bookDetail") private BookDetail bookDetail; public BookDetail getBookDetail() { return bookDetail; } public void setBookDetail(BookDetail bookDetail) { this.bookDetail = bookDetail; } public long getId() { return id; } public void setId(long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
BookDetail類,mappedBy 表示由Book類的bookDetail維護外鍵:
@Entity @Table(name = "bookdetail") @DynamicInsert(true) public class BookDetail implements Serializable{ private static final long serialVersionUID = 1L; /** * 主鍵 */ @Id @Column(name = "id") @GeneratedValue(strategy = GenerationType.IDENTITY) private long id; @Column(name = "numOfPages") private int numOfPages; @OneToOne(cascade = CascadeType.ALL, mappedBy = "bookDetail") private Book book; public Book getBook() { return book; } public void setBook(Book book) { this.book = book; } public long getId() { return id; } public void setId(long id) { this.id = id; } public int getNumOfPages() { return numOfPages; } public void setNumOfPages(int numOfPages) { this.numOfPages = numOfPages; } }
book表:
bookdetail表:
保存Book對象的時候,會先將Bookdetail對象保存,然后設置Book對象外鍵,並保存。即先保存targetEntity,設置外鍵后,再保存sourceEntity。
@OneToMany
@OneToMany與@JoinColumn結合使用,會在目標實體(targetEntity指定的類中創建外鍵)。報存的時候,先保存sourceEntity,設置外鍵后,再保存targetEntity。下方代碼是一對多的情況:
@OneToMany(targetEntity = SubVO.class, cascade=CascadeType.ALL) @JoinColumn(name="conditionid") private List<SubVO> subVO = new ArrayList<>();
針對其他級聯關系和級聯類型的介紹,可參照JPA概念解析:CascadeType(各種級聯操作)詳解。
需要注意的是:
(1)多對多情況,可以不用這種注解的方式,可以通過中間表維護級聯關系(比如A和B表多對多,C表只包含2列A和B的主鍵映射,維護多對多關系),操作可能更方便。
(2)這種級聯謹慎使用,在查詢等操作的時候,查A實體,也會把級聯的B或C實體也查出來,但業務只需要A的信息,所以可能增加數據庫負擔。
參考:https://www.jianshu.com/p/8ae19b367a1b