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


前言

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

one to many關系映射

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

單向關聯(@OneToMany)

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

@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配置生成單向關聯的情況,這看起來更像是多對多數據庫關聯,而不是一對多關系,理論上應該只有兩個表而不是三個表,所以我們需要使用不必要的空間來存儲數據,這樣效率不高,我們只有兩個外鍵,而不僅僅是一個外鍵,但是,由於我們最有可能對這些外鍵進行索引,因此我們將需要兩倍的內存來緩存此關聯的索引。

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

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

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

 

接下來我們打開會話來保存數據看看,如下:

        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首先插入沒有外鍵的子記錄,然后在處理目標集合階段,對外鍵列進行更新。 

雙向關聯(@OneToMany)

和我們一節講解一對一關系映射一樣,我們需要通過指定mappedBy屬性來配置雙向關聯,對目標實體集合和目標實體分別進行如下配置

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

總結 

本節我們講解了一對多映射關系,其實和一對一關系映射差不多,本文到此結束,講完多對多關系,我們進入到對數據的操作。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM