jpa多对一映射

1.插入
建一个部门类Dept和一个员工类Emp;
Emp对Dept是多对一的关系;因为一个部门有多个员工,而一个员工只有一个部门;
 
Emp类中添加一个Dept的属性;
@ManyToOne注解表示了员工和部门是多对一的关系;
@JoinColumn注解的name属性表示外键名;Emp表中会多出一个外键列;
//多对一,一个员工对应一个部门;而一个部门可对应多个员工;
     @JoinColumn(name="d_id")
     @ManyToOne
     private Dept dept;
 
插入测试:
//测试多对一添加
     @Test
     public void testUpdate() {
           //部门1
           Dept dept=new Dept();
           dept.setDname("军师");
           //员工1
           Emp emp=new Emp();
           emp.setBirthday(new Date());
           emp.setName("诸葛孔明");
           emp.setSalary(1000);
           emp.setDept(dept);
           //员工2
           Emp emp2=new Emp();
           emp2.setBirthday(new Date());
           emp2.setName("小懿子");
           emp2.setSalary(5000);
           emp2.setDept(dept);
           //插入
           manager.persist(dept);
           manager.persist(emp);
           manager.persist(emp2);
     }
结果:
Hibernate:
    insert
    into
        tb_dept
        (dname)
    values
        (?)
Hibernate:
    insert
    into
        tb_emp
        (birthday, d_id, name, salary)
    values
        (?, ?, ?, ?)
Hibernate:
    insert
    into
        tb_emp
        (birthday, d_id, name, salary)
    values
        (?, ?, ?, ?)
可以看出,先插入Dept也就是少的一方,执行三条insert语句;
 
先插入Emp,后插入Dept结果:
Hibernate:
    insert
    into
        tb_emp
        (birthday, d_id, name, salary)
    values
        (?, ?, ?, ?)
Hibernate:
    insert
    into
        tb_emp
        (birthday, d_id, name, salary)
    values
        (?, ?, ?, ?)
Hibernate:
    insert
    into
        tb_dept
        (dname)
    values
        (?)
Hibernate:
    update
        tb_emp
    set
        birthday=?,
        d_id=?,
        name=?,
        salary=?
    where
        id=?
Hibernate:
    update
        tb_emp
    set
        birthday=?,
        d_id=?,
        name=?,
        salary=?
    where
        id=?
可以看出,先执行了三条插入语句,后执行了两条update语句;
因为Emp先插入时由于Dept还没插入,所以没有Dept的did;也就是外键;
等Dept插入后有了外键;
为了维持两张表的关联关系,执行了更新语句;给两个Emp添加外键;
 
为了提高效率,处理多对一的保存操作时,最好先保存少的一方;
 
2.查询
@Test
     public void testSelect(){
           manager.find(Emp.class, 1);
     }
结果:
Hibernate:
    select
        emp0_.id as id1_1_1_,
        emp0_.birthday as birthday2_1_1_,
        emp0_.d_id as d_id5_1_1_,
        emp0_.name as name3_1_1_,
        emp0_.salary as salary4_1_1_,
        dept1_.did as did1_0_0_,
        dept1_.dname as dname2_0_0_
    from
        tb_emp emp0_
    left outer join
        tb_dept dept1_
            on emp0_.d_id=dept1_.did
    where
        emp0_.id=?
可以看出使用左外连接来获取关联对象;
 
1)懒加载查询
可在@ManyToOne注解后面将fetch属性改为LAZY来使用懒加载;
懒加载会在需要用到Dept的属性时才执行查询Dept的sql语句;可以节省资源;
//多对一,一个员工对应一个部门;而一个部门可对应多个员工;
     @JoinColumn(name="d_id")
     @ManyToOne(fetch=FetchType.LAZY)
     private Dept dept;
结果:
Hibernate:
    select
        emp0_.id as id1_1_0_,
        emp0_.birthday as birthday2_1_0_,
        emp0_.d_id as d_id5_1_0_,
        emp0_.name as name3_1_0_,
        emp0_.salary as salary4_1_0_
    from
        tb_emp emp0_
    where
        emp0_.id=?
可以看出没有查询外键;
 
3.删除
因为有外键关联;在删除多对一,少的一方时会报错;
例如当Dept的一条记录还被Emp中的记录关联时,就无法删除,会报错;
 
4.更新
在many to one 映射中,可以通过one的一方来修改many;
//测试修改
     @Test
     public void testUpdate(){
           Emp emp=manager.find(Emp.class, 1);
           emp.getDept().setDname("丞相");
     }
结果:
Hibernate:
    select
        emp0_.id as id1_1_0_,
        emp0_.birthday as birthday2_1_0_,
        emp0_.d_id as d_id5_1_0_,
        emp0_.name as name3_1_0_,
        emp0_.salary as salary4_1_0_
    from
        tb_emp emp0_
    where
        emp0_.id=?
Hibernate:
    select
        dept0_.did as did1_0_0_,
        dept0_.dname as dname2_0_0_
    from
        tb_dept dept0_
    where
        dept0_.did=?
Hibernate:
    update
        tb_dept
    set
        dname=?
    where
        did=?
可以看出执行了两条查询语句和一条更新语句;
 
 
 
 
 
 
 
原文地址:https://www.cnblogs.com/ShiningArmor/p/10562491.html