Hibernate入門之one to many關係映射詳解

前言

關係映射只有正確的配置才能生成正確而有效的SQL語句,經過上一節對一對一關係的講解,咱們發現其實並不難,在關係數據庫系統中,一對多關聯基於外鍵列連接兩個表,以便子表記錄引用父錶行的主鍵。數據庫

one to many關係映射

對於一對多關係映射也存在單向和雙向關聯,在JPA中,咱們經過註解@OneToMany和@ManyToOne來進行單向或雙向關聯,雙向關聯要求目標實體映射提供@ManyToOne註解,該註解負責控制關,單向關聯經過註解@OneToMany配置更簡單,由於它是定義關係的父方,接下來咱們分別來說解單向和雙向關聯。緩存

單向關聯(@OneToMany)

咱們給出實體Blog和Post實體,一個博客對應下有多篇發表文章,而一篇文章只屬於特定博客,以下:session

@Entity
public class Blog {
    @Id
    private Long id;

    @Column
    private String name;

    @OneToMany(cascade = CascadeType.ALL)
    private List<Post> posts  = new ArrayList<>();

    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;
    }

    public void addPost(Post post) {
        posts.add(post);
        post.setBlog(this);
    }

    public void addPosts(List<Post> posts) {
        for (Post p : posts) {
            addPost(p);
        }
    }
}
@Entity
public class Post {

    @Id
    @GeneratedValue
    private Long id;

    @ManyToOne
    private Blog blog;

    private String title;

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public Blog getBlog() {
        return blog;
    }

    public void setBlog(Blog blog) {
        this.blog = blog;
    }
}

 

如上就是默認狀況下經過註解@OneToMany配置生成單向關聯的狀況,這看起來更像是多對多數據庫關聯,而不是一對多關係,理論上應該只有兩個表而不是三個表,因此咱們須要使用沒必要要的空間來存儲數據,這樣效率不高,咱們只有兩個外鍵,而不單單是一個外鍵,可是,因爲咱們最有可能對這些外鍵進行索引,所以咱們將須要兩倍的內存來緩存此關聯的索引。app

單向關聯(具備@JoinColumn的@OneToMany)

要解決生成上述額外的聯接表問題,咱們只須要在目標實體集合中繼續添加@JoinColumn註解,經過@JoinColumn註解可幫助Hibernate找出在post表中有一個blog_id外鍵列來定義此關聯。以下:post

    @OneToMany(cascade = CascadeType.ALL)
    @JoinColumn(name = "blog_id")
    private List<Post> posts = new ArrayList<>();

 

接下來咱們打開會話來保存數據看看,以下:this

        Blog blog = new Blog();
        blog.setId(1L);
        blog.setName("Jeffcky");

        Post post = new Post();
        post.setTitle("hibernate4");

        Post post1 = new Post();
        post1.setTitle("hibernate5");

        blog.addPosts(Arrays.asList(post, post1));

        ......

        session.save(blog);

此時咱們發現對於實體Post中的外鍵blog_id並非直接插入,而是在插入後再進行更新,這裏涉及到JPA中的實體狀態,很明顯在處理目標集合以前就進行了持久化操做,如此這樣,因爲目標實體不存儲此信息,所以Hibernate首先插入沒有外鍵的子記錄,而後在處理目標集合階段,對外鍵列進行更新。 spa

雙向關聯(@OneToMany)

和咱們一節講解一對一關係映射同樣,咱們須要經過指定mappedBy屬性來配置雙向關聯,對目標實體集合和目標實體分別進行以下配置hibernate

    @OneToMany(mappedBy = "blog", cascade = CascadeType.ALL)
    private List<Post> posts  = new ArrayList<>();
    @ManyToOne
private Blog blog;

總結 

本節咱們講解了一對多映射關係,其實和一對一關係映射差很少,本文到此結束,講完多對多關係,咱們進入到對數據的操做。3d

相關文章
相關標籤/搜索