• JPA学习笔记(8)——映射双向一对多关联关系


    双向一对多关联关系

    前面的博客讲的都是单向的,而本问讲的是双向的(双向一对多 = 双向多对一)

    什么是双向?

    我们来对照一下单向和双向

    单向/双向 User实体类中是否有List< Order> orders Order实体类中是否有User user
    单向多对一
    单向一对多
    双向一对多(双向多对一)


    怎么构建关系

    User实体类

    package com.jpa.helloworld2;
    
    import java.util.ArrayList;
    import java.util.List;
    
    import javax.persistence.CascadeType;
    import javax.persistence.Column;
    import javax.persistence.Entity;
    import javax.persistence.FetchType;
    import javax.persistence.GeneratedValue;
    import javax.persistence.GenerationType;
    import javax.persistence.Id;
    import javax.persistence.JoinColumn;
    import javax.persistence.OneToMany;
    import javax.persistence.Table;
    
    
    @Table(name="T_USER")
    @Entity
    public class User {
    
        @Column(name="ID")
        @GeneratedValue(strategy=GenerationType.AUTO)
        @Id
        private Integer id;
    
        @Column(name="NAME")
        private String name;
    
        @JoinColumn(name="USER_ID")
        @OneToMany
        private List<Order> orders = new ArrayList<>();
    
        public Integer getId() {
            return id;
        }
        public void setId(Integer id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public List<Order> getOrders() {
            return orders;
        }
        public void setOrders(List<Order> orders) {
            this.orders = orders;
        }
        @Override
        public String toString() {
            return "User [id=" + id + ", name=" + name + ", orders=" + orders + "]";
        }
    
    }
    

    Order实体类

    package com.jpa.helloworld2;
    
    import javax.persistence.Column;
    import javax.persistence.Entity;
    import javax.persistence.FetchType;
    import javax.persistence.GeneratedValue;
    import javax.persistence.GenerationType;
    import javax.persistence.Id;
    import javax.persistence.JoinColumn;
    import javax.persistence.ManyToOne;
    import javax.persistence.Table;
    import javax.persistence.TableGenerator;
    
    @Table(name="T_ORDER")
    @Entity
    public class Order {
    
        @Column(name="ID")
        @GeneratedValue
        @Id
        private Integer id;
    
        @Column(name="ORDER_NAME")
        private String orderName;
    
        @JoinColumn(name="USER_ID")
        @ManyToOne
        private User user;
    
        public Integer getId() {
            return id;
        }
    
        public void setId(Integer id) {
            this.id = id;
        }
    
        public String getOrderName() {
            return orderName;
        }
    
        public void setOrderName(String orderName) {
            this.orderName = orderName;
        }
    
        public User getUser() {
            return user;
        }
    
        public void setUser(User user) {
            this.user = user;
        }
    
        @Override
        public String toString() {
            return "Order [id=" + id + ", orderName=" + orderName + ", user="
                    + user + "]";
        }
    }
    

    注意,两个实体类中的@JoinColumn(name=”USER_ID”) 值要一致

    插入

    Order order1 = new Order();
    order1.setOrderName("o1");
    
    Order order2 = new Order();
    order2.setOrderName("o2");
    
    User user = new User();
    user.setName("tom");
    user.getOrders().add(order1);
    user.getOrders().add(order2);
    
    order1.setUser(user);
    order2.setUser(user);
    
    entityManager.persist(user);
    entityManager.persist(order1);
    entityManager.persist(order2);

    注意:既要把user放到order中。也要把order加到user中

    结果
    这里写图片描写叙述

    看截图,你会发现有两次的udpate操作,这是由于要维护关联关系。

    假设你先插入两个order,在插入user,将会发现有四次的update操作。这会影响效率。

    要怎么解决呢?

    在这种一对多的情况下,我们能够指明由“一”的一方来维护关联关系:在User实体类中

    @OneToMany(mappedBy="user")
    private List<Order> orders = new ArrayList<>();

    注意:使用了mappedBy之后,就不能使用@JoinColumn注解,否则抛异常

    再次运行插入操作,发现没有再多出update操作了

    这里写图片描写叙述

    总结:在一对多和多对一的情况下,插入操作要先插入“一”的对象。再插入“多”的对象。这样能够降低sql语句。假设是双向的,要使用mappedBy指明由“多”的一方(Order)中的user来维护关联关系

    查询

    User u = entityManager.find(User.class, 3);
    System.out.println(u.getName());
    
    System.out.println(u.getOrders().get(0).getOrderName());

    这段代码查询没问题,可是假设这样写:

    User u = entityManager.find(User.class, 3);
    System.out.println(u);

    会出现这种结果:
    这里写图片描写叙述

    这是由于我的User类和Order类都重写了toString()方法。

    打印一个对象事实上就是调用它的toString()方法。而User中有orders,Order中有user。互相调来调去。导致无限死循环下去。因此出现了栈溢出的异常

  • 相关阅读:
    layui框架如何在停止服务用户操作任何步骤自动跳转登录页
    h5移动端和ios以及安卓客户端的接口联调
    sublime 主要使用方法
    内外边距、浮动、布局相关
    js介绍
    css的三个特性 背景透明设置
    选择器 导航制作相关
    表单综合
    自定义列表dl
    相对路径和绝对路径
  • 原文地址:https://www.cnblogs.com/zsychanpin/p/7295529.html
Copyright © 2020-2023  润新知