• jpa单向一对多


    单向一对多是一个类中的一条记录可对应另一个类的多条记录;
    比如一个部门可对应多个员工;
     
    jpa中的实现步骤:
        one-to-many的one类中添加一个many类类型的set;比如部门类Dept中添加一个员工类的Set<Emp>;
        在set属性上方添加注解@one-to-many,表示映射one-to-many关系;
        在set属性前添加注解@JoinColumn注解,注解的name属性为one类的主键,用来映射外键列名;
    //一对多关联
         @JoinColumn(name="id")
         @OneToMany
         private Set<Emp> empSet;
      
    1.插入
    代码:
    //测试一对多
         @Test
         public void testInsert(){
               Emp e1=new Emp();
               e1.setBirthday(new Date());
               e1.setName("诸葛村夫");
               e1.setSalary(2000);
               Emp e2=new Emp();
               e2.setBirthday(new Date());
               e2.setName("王司徒");
               e2.setSalary(5000);
               Dept dept=new Dept();
               dept.setDname("文官");
               Set set=new HashSet<Emp>();
               set.add(e1);
               set.add(e2);
               dept.setEmpSet(set);
               //执行保存操作
               manager.persist(e1);
               manager.persist(e2);
               manager.persist(dept);
         }
    结果:
    Hibernate:
        insert
        into
            tb_emp
            (birthday, name, salary)
        values
            (?, ?, ?)
    Hibernate:
        insert
        into
            tb_emp
            (birthday, name, salary)
        values
            (?, ?, ?)
    Hibernate:
        insert
        into
            tb_dept
            (dname)
        values
            (?)
    Hibernate:
        update
            tb_emp
        set
            id=?
        where
            did=?
    Hibernate:
        update
            tb_emp
        set
            id=?
        where
            did=?
    可以看出,执行了三条插入语句和两条更新语句;
    由于是one的一端通过外键来维持关联关系;
    在保存many的一端时,就不会保存外键;
    只能通过update语句来向many的一段插入外键;
    因此无论先插入many还是先插入one都会有update语句;
     
    2.查找
    一对多映射,默认对many的一端使用懒加载的策略;
    代码:
    //测试一对多查询
         @Test
         public void testFind(){
               manager.find(Dept.class, 1);
         }
    结果:
    Hibernate:
        select
            dept0_.did as did1_0_0_,
            dept0_.dname as dname2_0_0_
        from
            tb_dept dept0_
        where
            dept0_.did=?
    可以看出只查询了dept,也就是one的一方;many的一方只会在用到时查询;
    如果向改变加载策略;可在@OneToMany注解后面的fetch属性修改为EAGER;
     
    3.删除
    删除one的一端时,会将one一端关联的many一端的外键通过update语句置空;然后再删除one的一端;
    如果想在删除one一端的同时把关联的many一端同时删除;可以在@OneToMany注解后面加上属性cascade={CascadeType.REMOVE};
         @JoinColumn(name="id")
         @OneToMany(cascade={CascadeType.REMOVE})
         private Set<Emp> empSet;
     
    代码:
         //测试删除
         @Test
         public void testRemove(){
               Dept dept=manager.find(Dept.class, 1);
               manager.remove(dept);
         }
    结果:
    Hibernate:
        select
            dept0_.did as did1_0_0_,
            dept0_.dname as dname2_0_0_
        from
            tb_dept dept0_
        where
            dept0_.did=?
    Hibernate:
        update
            tb_emp
        set
            id=null
        where
            id=?
    Hibernate:
        delete
        from
            tb_dept
        where
            did=?
     
    4.修改
    可以通过one的一方来修改many的一方;
    例如代码:
         //测试修改
         @Test
         public void testUpdate(){
               Dept dept=manager.find(Dept.class,1);
               dept.getEmpSet().iterator().next().setSalary(99999);
         }
    可改变关联的第一条数据的salary属性;
     
     
     
      
  • 相关阅读:
    ASP.NET 防盗链的实现[HttpHandler]
    html打印表格每页都有的表头和打印分页
    spring是怎样管理mybatis的及注入mybatis mapper bean的
    浅谈Log4j和Log4j2的区别
    git tag — 标签相关操作
    java cocurrent包
    线程实现异步
    使用Shell脚本查找程序对应的进程ID,并杀死进程
    shell脚本监测文件变化
    spring boot的几种配置类型
  • 原文地址:https://www.cnblogs.com/ShiningArmor/p/10575764.html
Copyright © 2020-2023  润新知