zoukankan      html  css  js  c++  java
  • 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;

    总结 

    本节我们讲解了一对多映射关系,其实和一对一关系映射差不多,本文到此结束,讲完多对多关系,我们进入到对数据的操作。

  • 相关阅读:
    下个月去北京了,心如一团乱麻好多事情要解决,但是不知道从哪里开始,还是顺其自然吧,一件件的解决
    C# SQLServer 数据库连接类
    C#页面缓存写法
    从北京站到天通苑怎么走,
    工作描述的介绍|如何写工作描述
    网线制作方法|国标网线制作方法|常用的网线制作方法
    递归删除空文件夹
    如何使用股票行情软件看股票
    正则批量验证函数
    简单的游标更新日期例子
  • 原文地址:https://www.cnblogs.com/CreateMyself/p/12436179.html
Copyright © 2011-2022 走看看