zoukankan      html  css  js  c++  java
  • JPA ---- 表之间的映射关系

    一、单向多对一关系:
       @Entity
        @Table(name="jpa_order")
        public class Order {
           private Integer id;
           private String orderName;
           private Customer customer;
         
           @GeneratedValue(strategy=GenerationType.AUTO)
           @Id
           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;
           }
         
           @JoinColumn(name="customer_id")
           @ManyToOne
           public Customer getCustomer() {
               return customer;
           }
           public void setCustomer(Customer customer) {
               this.customer = customer;
           }
     }
    二、单向一对多关系:
        @Table(name="jpa_customer")
        @Entity
        public class Customer {
           private Integer id;
           private String lastName;
           private String email;
           private Integer age;
           private Date birthday;
           private Date createTime;
           private Set<Order> orders = new HashSet<>();
         
           @GeneratedValue(strategy=GenerationType.AUTO)
           @Id
           public Integer getId() {
                return id;
           }
           public void setId(Integer id) {
               this.id = id;
           }
           @Column(name="last_name")
           public String getLastName() {
               return lastName;
            }
           @Temporal(TemporalType.DATE)
           public Date getBirthday() {
               return birthday;
           }
           public void setBirthday(Date birthday) {
               this.birthday = birthday;
           }
           @Temporal(TemporalType.TIMESTAMP)
           public Date getCreateTime() {
               return createTime;
           }
           public void setCreateTime(Date createTime) {
               this.createTime = createTime;
           }
           @JoinColumn(name="customer_id")
           @OneToMany(cascade=CascadeType.REMOVE)
           public Set<Order> getOrders() {
                return orders;
           }
           public void setOrders(Set<Order> orders) {
                this.orders = orders;
            }
         }
      1、插入
       不管先插入多大一端还是一的一端,最终打印的sql语句数量是一样的,因为是由一的一端维护关联关系,所以在插入多的一端时它并不会保存外键值,只有在持久化之后再另外发送update语句更新多的一端的外键值
      2、删除
        多的一端可以随意删除,主要说一下一的一端
        在单向多对一的时候一的一端是不可以删除的
        而单项一对多的不同,可以删除一的一端,那么多的一端会被怎么操作呢?根据发出的sql语句可以看出,在默认情况下,删除一的一端,多的一端的外键会被置为null。那么接下来就说一下怎么设置对多的一端的操作。
     
       3、在@OneToMany注解中有一个cascade属性,它的值是一个CascadeType类的数组
            ALL :级联所有实体状态转换
          PERSIST :级联实体持久化操作。
           MERGE :级联实体合并操作。
          REMOVE :级联实体删除操作。
         REFRESH :级联实体刷新操作。
           DETACH :级联实体分离操作。
    二、双向一对一关系: 一个部门有一个经理,一个经理管一个部门
     1、department类
       @Entity
         @Table(name="jpa_department")
         public class Department {
           @Id
           @GeneratedValue(strategy=GenerationType.AUTO)
           private Integer id;
           @Column(name="dep_name")
           private String depName;
         
           @JoinColumn(name="manager_id")
           @OneToOne
           private Manager manager;
        }
      2、Manager类
        @Entity
           @Table(name="jpa_manager")
           public class Manager {
             @Id
             @GeneratedValue(strategy=GenerationType.AUTO)
             private Integer id;
             private String name;
         
             @OneToOne(mappedBy="manager")
             private Department department;
         }
      3、插入:
          Manager manager = new Manager();
              manager.setName("王强");
              
              Department department = new Department();
              department.setDepName("销售部");
              
              manager.setDepartment(department);
              department.setManager(manager);
              
              entityManager.persist(manager);
              entityManager.persist(department);
         关于插入的顺序,先插入不维护关联关系的一方,即manager(没有外键的一方)
      
       4、查询:查询维护关联关系的一方(有外键的一方)
               Department dept = entityManager.find(Department.class, 1);
             System.out.println(dept.getDeptName());
         如果只想要department,不想要manager。可以用fetch更改为懒加载策略:在department实体类中加入
         @OneToOne(fetch=FetchType.LAZY)
         private Manager manager;
     
      5、查询不维护关联关系的一方(没有外键的一方)
         Manager m = entityManager.find(Manager.class, 1);
         System.out.println(m.getName());
       
       运行发现,查询manager时,一定会去查department,即使用fetch改为懒加载策略,结果也是一样的。
       不同的时,如果改为懒加载,将会执行两个sql语句查询。默认情况下是执行一句sql语句关联查询。因此不推荐设置fetch
     
      注意: 一定会查询两个对象的原因:
        (1) 在查询manager表时,没有外键,jpa不知道该怎么处理Manager中的关联对象,因此它一定会去department表中查看有没有相应的记录。
       (2) 在查询department时,因为有外键,所以jpa很容易的知道该怎么处理关联对象:要么返回一个代理,要么返回对象)
  • 相关阅读:
    laravel报错1071 Specified key was too long; max key length is 1000 bytes
    【laravel】Eloquent 模型事件和监听方式
    angular使用forRoot() 注册单一实例服务
    js判断电脑是windows系统还是mac系统
    扁平数据根据`parentId`生成树结构
    页面滚动到指定元素区域
    js简洁模式代码
    简单git使用命令
    图片懒加载 echo.js
    页面图片预加载与懒加载
  • 原文地址:https://www.cnblogs.com/lone5wolf/p/10940844.html
Copyright © 2011-2022 走看看