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

相关文章
相关标签/搜索