映射关系详解

表关系映射(双向映射):

  • @OneToOne 一对一关系

  • @OneToMany 一对多

  • @ManyToMany(不推荐使用,而是采用用中间对象,把多对多拆成两个对多一关系,如下书 与作者 的关系例子,还可以使用中间表用来搜索)

字段映射(单向映射):

  • @Embedded, @Embeddable 嵌入式关系(单向映射)

  • @ElementCollection 集合一对多关系(单向映射)

注意:hibernate jpa中 的 fetch

fetch 为关键映射的一个加载策略

fetch的默认值:FetchType.EAGER,也就是加载的时候把响应的映射关系数据也加载出来

如果这不适合于应用程序或特定的持久字段,请将fetch设置为FetchType.LAZY,延迟加载,只要getxxxx(),具体获取时,再次执行一条sql语句获取

@OneToOne 一对一关系

@OneToOne 属性

比如作者和作者详情信息(一些不常用信息),就是一个一对一

Author.java

@Entity
public class Author {
    @OneToOne
    private AuthorInfo info;
    ...... 省略其他
}

AuthorInfo.java

@Entity
public class AuthorInfo {

    private String school;

    @OneToOne(mappedBy = "info")
    private Author author;

    ......省略其他
}

无属性的一方拥有管理权,也就是author 表中会多出来一个字段info_id

@OneToMany 一对多, @ManyToOne 多对一

注意一对多关系映射时,“One”端采用@OneToMany 注释时必须使用mappedBy来指定Many端的对象的哪个属性提供了对应的关系映射。

避免建立单向关系映射,以免产生新的中间表,而采用双向映射关系(这样many 的一端只会使用外键方式来维护关系)

@ManyToOne 的属性

@OneToMany 属性

一本书有多个作者(OneToMany 一对多), 而书和作者表中,("spring boot", revin")只能属于一本书(ManyToOne 多对一)

Book.java

@Entity
public class Book {

    private String name;

    @OneToMany(mappedBy = "book")
    private List<BookAuthor> authors;

    .....省略
}

一个作者出版了多本书(OneToMany 一对多), 而书和作者表中,("spring boot", revin")只能属于一个作者(ManyToOne 多对一)

Author.java

@Entity
public class Author {
    @OneToMany(mappedBy = "author")
    //@OrderBy("book.name ASC")
    private List<BookAuthor> books;
     .....省略
}

BookAuthor .java

@Entity
public class BookAuthor {

    @ManyToOne
    private Book book;

    @ManyToOne
    private Author author;
    .....省略
}

比如一本书可以分属于多个栏目(OneToMany 一对多),而同一个栏目 只能有一本相同的书(ManyToOne 多对一)

Book.java

@Entity
public class Book {

    private String name;

    @ManyToOne
    private Category category;

    .....省略
}

Category.java

public class Category {
@OneToMany(mappedBy = "category")
    private List<Book> books;

    ......省略其他
}

@Embedded, @Embeddable 嵌入式关系

意思就是说当你有一个用户信息表中,这个人有地址信息,而地址信息有可能别的类有其他的关系映射,所以需要独立处理,但是address表中的字段,你有需要在用户表中存在这可以这种嵌入式关系。

@Embedded嵌入Address 类

@Entity
public class Author {
    @Embedded
    private Address address;
    ......  省略其他
}

@Embeddable声明Address 类是可嵌入的

@Embeddable
public class Address {

    private String province;

    private String city;

    private String area;

    private String address;

    private String zipcode;

    ...... 省略其他

}

最后生成出来 author表中会包含province,city,area,address,zipcode这些字段。

@ElementCollection 集合一对多关系

@Entity
public class Author {

    @id
    @GeneratedValue
    private long id

    @ElementCollection
    private List<String> hobbies;
    ......  省略其他
}

生成效果为:数据表会出现一张新表为author_hobbies,并且字段名为author_id 和 hobbies , Author表与hobbies表产生了一个一对 的关系。

当你插入和获取用户信息的时,jpa会自动关联。

再举例子

当一个用户有多个地址,比如在电子商务场景中,会有多个收货地址

@Entity
public class Author {

    @ElementCollection
    private List<Address> addresses;
    ......  省略其他
}

也会重新生成一张新表,并且字段名是Address类定义的字段。Author与addresses产生一个一对的关系。

资料

1JPA 批注参考 - 推荐当手册用

Last updated