Java for Web学习笔记(一二八)映射(4)OneToMany和ManyToOne

OneToMany和ManyToOne是更为常见的例子。如果A和B的关系是OneToMany,则B和A的关系就是ManyToOne。

小例子

我们继续前面书的例子,增加书评表。一本书可以有多条书评,一条书评对应一本书。

CREATE TABLE Book (
  Id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
  BookName VARCHAR(50) NOT NULL
) ENGINE = InnoDB;

CREATE TABLE Book_Comment (
  Id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
  Commentator VARCHAR(32) NOT NULL,
  Book_Id BIGINT UNSIGNED NOT NULL,  
  Comment VARCHAR(1024) NOT NULL,
  CONSTRAINT `BOOK_BOOK_COMMENT` FOREIGN KEY (`Book_Id`) REFERENCES Book (`Id`) ON DELETE CASCADE
) ENGINE = InnoDB;

单向的ManyToOne

Book和普通的Entity没有区别,BookComment如下

@Entity(name = "Book_Comment")
public class BookComment {
    private long id;
    private String commentator;
    private Book book; 
    private String comment;
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    public long getId() { ... } 

    /* 【1】标记这是一个ManyToOne的关系,且对方必须存在(optional = false) */
    @ManyToOne(optional = false)
    /* 【2】@JoinColumn是用来标记关联两个表的列。*/
    @JoinColumn(name = "Book_Id")
    public Book getBook() { ...}

    ......
}

单向的OneToMany

作为Many的BookComment和普通的Entity无异,Book如下:

@Entity
public class Book {
    private long id;
    private String bookName;	
    private Set<BookComment> comments = new HashSet<>();

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    public long getId() { ... }

    /* 【1】标记OneToMany,要求如果删除了相关的BookComment信息,则对方表格的信息也删除(orphanRemoval = true)
     * 【2】只要是单向关系,都应该提供@JoinColumn信息:OneToMany给的对方表格关联本表格主键的列,也即对方表格的外键。*/
    @OneToMany(fetch = FetchType.LAZY,cascade = CascadeType.ALL, orphanRemoval = true)
    @JoinColumn(name = "Book_Id")
    public Set<BookComment> getComments() { ... }

   ......
}

双向OneToMany和ManyToOne

ManyToOne和单向的ManyToOne没有什么区别

@Entity(name = "Book_Comment")
public class BookComment {
    ... ...
    private Book book; 

    /* 【1】标记这是一个ManyToOne的关系,且对方必须存在(optional = false) */
    /* 【2】@JoinColumn是用来标记关联两个表的列。*/
    @ManyToOne(optional = false)
    @JoinColumn(name = "Book_Id")
    public Book getBook() { ...}

    ......
}

OneToMany中通过mappedby表示双向映射,而不是两个单向。

@Entity
public class Book {
    ... ...
    private Set<BookComment> comments = new HashSet<>();

    /* 【1】标记OneToMany,给出了关系的另一头(BookComment)中哪个属性和本entity对应
     * 【2】已经有了mappedBy表明关联关系,无需@JoinColumn */
    @OneToMany(fetch = FetchType.LAZY,cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "book")
    public Set<BookComment> getComments() { ... }

   ......
}

带排序的List

小例子我们使用了Set,还可以使用List,Map等集合方式,可以指定特定的排序。

@Entity
public class Book {
    ... ...
    private List<BookComment> comments = new ArrayList<>();

    @OneToMany(fetch = FetchType.LAZY,cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "book") 
    /* List里面的元素将按BookComment的属性commentator进行排序。 */
    @OrderBy("commentator")
    public Set<BookComment> getComments() { ... }

   ......
}

使用Map,指定Key

@Entity
public class Book {
    ... ...
    private Map<String,BookComment> comments = new HashMap<>();

    @OneToMany(fetch = FetchType.LAZY,cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "book") 
    /* 以BookComment的属性commentator作为Key。 
     * 由于Map的特点,如果一个评论员有两条评论,在map中只会有一条。Map不适用于本小场景,只是说明一种方式。 */
    @MapKey(name="commentator")
    public Set<BookComment> getComments() { ... }

   ......
}

 

相关链接:我的Professional Java for Web Applications相关文章

©️2020 CSDN 皮肤主题: 编程工作室 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值