Hibernate 一对一、一对多、多对多注解mappedBy属性的总结

mappedBy:

    所填内容必为本类在另一方的字段名。

    表示:本类放弃控制关联关系,所有对关联关系的控制,如:建立、解除与另一方的关系,都由对方控制,本类不管。举个例子:

Teacher和Student之间是多对多关联关系,在Student端的teachers字段的@ManyToMany注解里面,配置属性mappedBy = "students"。表示:学生没有资格控制与老师的关联关系(如:建立关系、删除关系),只有老师才有资格控制关联关系。学生不能说:”我们两做朋友吧“。(即使说了,也无济于事,老师当学生没说。即Hibernate把学生说的当作耳边风,虽然Hibernate也不会抛出异常,程序照样能运行)。但是,老师可以说,“我们做朋友吧”。那么,学生只能无任何拒绝理由地接受。同样,如果学生说,”我们从此一刀两断吧“,那也是没用的。只有老师说:“滚,有多远,滚多远,为师今日将你逐出师门,再也不想见到你”,那么,这才能有效地解除关联关系(注意:这是一个对象(对应数据库里的一行记录)和一个对象之间的关系,而不是表和表之间的关联关系。一对师生关系的解除,不能影响整个社会的师生关系)。

测试代码:(这是完整类,后面只贴出test1的代码,其他部分不变)

Hibernate 一对一、一对多、多对多注解mappedBy属性的总结
public class MappedByTest {
</span><span style="color: #0000ff;">private</span> <span style="color: #0000ff;">static</span><span style="color: #000000;"> SessionFactory sessionFactory;

</span><span style="color: #0000ff;">private</span><span style="color: #000000;"> Session session;

@BeforeClass
</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> beforeTest(){
    sessionFactory </span>=<span style="color: #000000;"> HibernateUtil.getSessionFactory();
}
@AfterClass
</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> afterTest(){
    sessionFactory.close();
}
@Before
</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> beginTransaction(){
    session </span>=<span style="color: #000000;"> sessionFactory.openSession();
    session.beginTransaction();
}
@After
</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> commitTransaction(){
    session.getTransaction().commit();
    session.close();
}

@Test
</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> execute(){
    test1();
}

</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> test1(){
    Student student1 </span>= <span style="color: #0000ff;">new</span> Student("学生张三",3<span style="color: #000000;">);
    Student student2 </span>= <span style="color: #0000ff;">new</span> Student("学生李四",4<span style="color: #000000;">);
    Teacher teacher1 </span>= <span style="color: #0000ff;">new</span> Teacher("老师王五",5<span style="color: #000000;">);
    Teacher teacher2 </span>= <span style="color: #0000ff;">new</span> Teacher("老师赵六",6<span style="color: #000000;">);
    
    List</span>&lt;Student&gt; students = <span style="color: #0000ff;">new</span> ArrayList&lt;&gt;<span style="color: #000000;">();
    students.add(student1);
    students.add(student2);
    List</span>&lt;Teacher&gt; teachers = <span style="color: #0000ff;">new</span> ArrayList&lt;&gt;<span style="color: #000000;">();
    teachers.add(teacher1);
    teachers.add(teacher2);
    
    session.save(teacher1);
    session.save(teacher2);
    student1.setTeachers(teachers);
    session.save(student1);
}

}

Hibernate 一对一、一对多、多对多注解mappedBy属性的总结

产生的结果:

 Hibernate 一对一、一对多、多对多注解mappedBy属性的总结

----------------------------------------------------------------------------------------

然后,清空数据库,做第二次测试:

Hibernate 一对一、一对多、多对多注解mappedBy属性的总结
public void test1() {
        Student student1 = new Student("学生张三", 3);
        Student student2 = new Student("学生李四", 4);
        Teacher teacher1 = new Teacher("老师王五", 5);
        Teacher teacher2 = new Teacher("老师赵六", 6);
    List</span>&lt;Student&gt; students = <span style="color: #0000ff;">new</span> ArrayList&lt;&gt;<span style="color: #000000;">();
    students.add(student1);
    students.add(student2);
    List</span>&lt;Teacher&gt; teachers = <span style="color: #0000ff;">new</span> ArrayList&lt;&gt;<span style="color: #000000;">();
    teachers.add(teacher1);
    teachers.add(teacher2);

    session.save(student1);
    session.save(student2);
    teacher1.setStudents(students);
    session.save(teacher1);
}</span></pre>
Hibernate 一对一、一对多、多对多注解mappedBy属性的总结

 产生的结果:

Hibernate 一对一、一对多、多对多注解mappedBy属性的总结

可见:在Student类的teachers字段的@ManyToMany注解上配置属性mappedBy = "students",所有Student类产生的对象均不能建立和老师的关联关系,只有老师可以。

----------------------------------------------------------------------------------------

然后,清空数据库,做第三次测试:

Hibernate 一对一、一对多、多对多注解mappedBy属性的总结
public void test1(){
        Student student1 = new Student("学生张三",3);
        Student student2 = new Student("学生李四",4);
        Teacher teacher1 = new Teacher("老师王五",5);
        Teacher teacher2 = new Teacher("老师赵六",6);
    List</span>&lt;Student&gt; students = <span style="color: #0000ff;">new</span> ArrayList&lt;&gt;<span style="color: #000000;">();
    students.add(student1);
    students.add(student2);
    List</span>&lt;Teacher&gt; teachers = <span style="color: #0000ff;">new</span> ArrayList&lt;&gt;<span style="color: #000000;">();
    teachers.add(teacher1);
    teachers.add(teacher2);
    
    
    </span><span style="color: #0000ff;">int</span> stuId = 4<span style="color: #000000;">;
    </span><span style="color: #0000ff;">int</span> teacherId = 6<span style="color: #000000;">;
    Student persistentStudent </span>= (Student)session.get(Student.<span style="color: #0000ff;">class</span><span style="color: #000000;">, stuId); 
    Teacher persistentTeacher </span>= (Teacher)session.get(Teacher.<span style="color: #0000ff;">class</span><span style="color: #000000;">, teacherId);
    persistentStudent.getTeachers().remove(persistentTeacher);
    session.update(persistentStudent);
}</span></pre>
Hibernate 一对一、一对多、多对多注解mappedBy属性的总结

控制台打出的SQL语句:

Hibernate 一对一、一对多、多对多注解mappedBy属性的总结
Hibernate: 
    select
        student0_.student_id as student_1_0_0_,
        student0_.age as age2_0_0_,
        student0_.name as name3_0_0_ 
    from
        student student0_ 
    where
        student0_.student_id=?
Hibernate: 
    select
        teacher0_.teacher_id as teacher_1_1_0_,
        teacher0_.age as age2_1_0_,
        teacher0_.name as name3_1_0_ 
    from
        teacher teacher0_ 
    where
        teacher0_.teacher_id=?
Hibernate: 
    select
        teachers0_.student_id as student_2_2_0_,
        teachers0_.teacher_id as teacher_1_2_0_,
        teacher1_.teacher_id as teacher_1_1_1_,
        teacher1_.age as age2_1_1_,
        teacher1_.name as name3_1_1_ 
    from
        ts_relation teachers0_ 
    inner join
        teacher teacher1_ 
            on teachers0_.teacher_id=teacher1_.teacher_id 
    where
        teachers0_.student_id=?
Hibernate 一对一、一对多、多对多注解mappedBy属性的总结

产生的结果:

Hibernate 一对一、一对多、多对多注解mappedBy属性的总结

----------------------------------------------------------------------------------------

然后,清空数据库,做第四次测试:

Hibernate 一对一、一对多、多对多注解mappedBy属性的总结
public void test1(){
        Student student1 = new Student("学生张三",3);
        Student student2 = new Student("学生李四",4);
        Teacher teacher1 = new Teacher("老师王五",5);
        Teacher teacher2 = new Teacher("老师赵六",6);
    List</span>&lt;Student&gt; students = <span style="color: #0000ff;">new</span> ArrayList&lt;&gt;<span style="color: #000000;">();
    students.add(student1);
    students.add(student2);
    List</span>&lt;Teacher&gt; teachers = <span style="color: #0000ff;">new</span> ArrayList&lt;&gt;<span style="color: #000000;">();
    teachers.add(teacher1);
    teachers.add(teacher2);
    
    
    </span><span style="color: #0000ff;">int</span> stuId = 4<span style="color: #000000;">;
    </span><span style="color: #0000ff;">int</span> teacherId = 6<span style="color: #000000;">;
    Student persistentStudent </span>= (Student)session.get(Student.<span style="color: #0000ff;">class</span><span style="color: #000000;">, stuId); 
    Teacher persistentTeacher </span>= (Teacher)session.get(Teacher.<span style="color: #0000ff;">class</span><span style="color: #000000;">, teacherId);
    persistentTeacher.getStudents().remove(persistentStudent);
    session.update(persistentTeacher);
}</span></pre>
Hibernate 一对一、一对多、多对多注解mappedBy属性的总结

控制台打出的SQL语句:

Hibernate 一对一、一对多、多对多注解mappedBy属性的总结
Hibernate: 
    select
        student0_.student_id as student_1_0_0_,
        student0_.age as age2_0_0_,
        student0_.name as name3_0_0_ 
    from
        student student0_ 
    where
        student0_.student_id=?
Hibernate: 
    select
        teacher0_.teacher_id as teacher_1_1_0_,
        teacher0_.age as age2_1_0_,
        teacher0_.name as name3_1_0_ 
    from
        teacher teacher0_ 
    where
        teacher0_.teacher_id=?
Hibernate: 
    select
        students0_.teacher_id as teacher_1_2_0_,
        students0_.student_id as student_2_2_0_,
        student1_.student_id as student_1_0_1_,
        student1_.age as age2_0_1_,
        student1_.name as name3_0_1_ 
    from
        ts_relation students0_ 
    inner join
        student student1_ 
            on students0_.student_id=student1_.student_id 
    where
        students0_.teacher_id=?
Hibernate: --------------------------注意这条
    delete 
    from
        ts_relation 
    where
        teacher_id=? 
Hibernate: 
    insert 
    into
        ts_relation
        (teacher_id, student_id) 
    values
        (?, ?)
Hibernate 一对一、一对多、多对多注解mappedBy属性的总结

产生的结果:

Hibernate 一对一、一对多、多对多注解mappedBy属性的总结

可见:在Student类的teachers字段的@ManyToMany注解上配置属性mappedBy = "students",所有Student类产生的对象均不能删除和老师的关联关系,只有老师可以。

----------------------------------------------------------------------------------------

 由此证明了之前所说的,mappedBy表示,本类防止控制和另一方的关联关系,所填内容必为本类在另一方的字段名。

注意:mappedBy和@JoinTable是互斥的,也就是说,@"关联关系注解"里面写了mappedBy属性,下面就不能再写@JoinTable。否则,Hibernate报异常。

原文地址:https://www.cnblogs.com/565261641-fzh/p/6653847.html

mappedBy:

    所填内容必为本类在另一方的字段名。

    表示:本类放弃控制关联关系,所有对关联关系的控制,如:建立、解除与另一方的关系,都由对方控制,本类不管。举个例子:

Teacher和Student之间是多对多关联关系,在Student端的teachers字段的@ManyToMany注解里面,配置属性mappedBy = "students"。表示:学生没有资格控制与老师的关联关系(如:建立关系、删除关系),只有老师才有资格控制关联关系。学生不能说:”我们两做朋友吧“。(即使说了,也无济于事,老师当学生没说。即Hibernate把学生说的当作耳边风,虽然Hibernate也不会抛出异常,程序照样能运行)。但是,老师可以说,“我们做朋友吧”。那么,学生只能无任何拒绝理由地接受。同样,如果学生说,”我们从此一刀两断吧“,那也是没用的。只有老师说:“滚,有多远,滚多远,为师今日将你逐出师门,再也不想见到你”,那么,这才能有效地解除关联关系(注意:这是一个对象(对应数据库里的一行记录)和一个对象之间的关系,而不是表和表之间的关联关系。一对师生关系的解除,不能影响整个社会的师生关系)。

测试代码:(这是完整类,后面只贴出test1的代码,其他部分不变)

Hibernate 一对一、一对多、多对多注解mappedBy属性的总结
public class MappedByTest {
</span><span style="color: #0000ff;">private</span> <span style="color: #0000ff;">static</span><span style="color: #000000;"> SessionFactory sessionFactory;

</span><span style="color: #0000ff;">private</span><span style="color: #000000;"> Session session;

@BeforeClass
</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> beforeTest(){
    sessionFactory </span>=<span style="color: #000000;"> HibernateUtil.getSessionFactory();
}
@AfterClass
</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> afterTest(){
    sessionFactory.close();
}
@Before
</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> beginTransaction(){
    session </span>=<span style="color: #000000;"> sessionFactory.openSession();
    session.beginTransaction();
}
@After
</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> commitTransaction(){
    session.getTransaction().commit();
    session.close();
}

@Test
</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> execute(){
    test1();
}

</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> test1(){
    Student student1 </span>= <span style="color: #0000ff;">new</span> Student("学生张三",3<span style="color: #000000;">);
    Student student2 </span>= <span style="color: #0000ff;">new</span> Student("学生李四",4<span style="color: #000000;">);
    Teacher teacher1 </span>= <span style="color: #0000ff;">new</span> Teacher("老师王五",5<span style="color: #000000;">);
    Teacher teacher2 </span>= <span style="color: #0000ff;">new</span> Teacher("老师赵六",6<span style="color: #000000;">);
    
    List</span>&lt;Student&gt; students = <span style="color: #0000ff;">new</span> ArrayList&lt;&gt;<span style="color: #000000;">();
    students.add(student1);
    students.add(student2);
    List</span>&lt;Teacher&gt; teachers = <span style="color: #0000ff;">new</span> ArrayList&lt;&gt;<span style="color: #000000;">();
    teachers.add(teacher1);
    teachers.add(teacher2);
    
    session.save(teacher1);
    session.save(teacher2);
    student1.setTeachers(teachers);
    session.save(student1);
}

}

Hibernate 一对一、一对多、多对多注解mappedBy属性的总结

产生的结果:

 Hibernate 一对一、一对多、多对多注解mappedBy属性的总结

----------------------------------------------------------------------------------------

然后,清空数据库,做第二次测试:

Hibernate 一对一、一对多、多对多注解mappedBy属性的总结
public void test1() {
        Student student1 = new Student("学生张三", 3);
        Student student2 = new Student("学生李四", 4);
        Teacher teacher1 = new Teacher("老师王五", 5);
        Teacher teacher2 = new Teacher("老师赵六", 6);
    List</span>&lt;Student&gt; students = <span style="color: #0000ff;">new</span> ArrayList&lt;&gt;<span style="color: #000000;">();
    students.add(student1);
    students.add(student2);
    List</span>&lt;Teacher&gt; teachers = <span style="color: #0000ff;">new</span> ArrayList&lt;&gt;<span style="color: #000000;">();
    teachers.add(teacher1);
    teachers.add(teacher2);

    session.save(student1);
    session.save(student2);
    teacher1.setStudents(students);
    session.save(teacher1);
}</span></pre>
Hibernate 一对一、一对多、多对多注解mappedBy属性的总结

 产生的结果:

Hibernate 一对一、一对多、多对多注解mappedBy属性的总结

可见:在Student类的teachers字段的@ManyToMany注解上配置属性mappedBy = "students",所有Student类产生的对象均不能建立和老师的关联关系,只有老师可以。

----------------------------------------------------------------------------------------

然后,清空数据库,做第三次测试:

Hibernate 一对一、一对多、多对多注解mappedBy属性的总结
public void test1(){
        Student student1 = new Student("学生张三",3);
        Student student2 = new Student("学生李四",4);
        Teacher teacher1 = new Teacher("老师王五",5);
        Teacher teacher2 = new Teacher("老师赵六",6);
    List</span>&lt;Student&gt; students = <span style="color: #0000ff;">new</span> ArrayList&lt;&gt;<span style="color: #000000;">();
    students.add(student1);
    students.add(student2);
    List</span>&lt;Teacher&gt; teachers = <span style="color: #0000ff;">new</span> ArrayList&lt;&gt;<span style="color: #000000;">();
    teachers.add(teacher1);
    teachers.add(teacher2);
    
    
    </span><span style="color: #0000ff;">int</span> stuId = 4<span style="color: #000000;">;
    </span><span style="color: #0000ff;">int</span> teacherId = 6<span style="color: #000000;">;
    Student persistentStudent </span>= (Student)session.get(Student.<span style="color: #0000ff;">class</span><span style="color: #000000;">, stuId); 
    Teacher persistentTeacher </span>= (Teacher)session.get(Teacher.<span style="color: #0000ff;">class</span><span style="color: #000000;">, teacherId);
    persistentStudent.getTeachers().remove(persistentTeacher);
    session.update(persistentStudent);
}</span></pre>
Hibernate 一对一、一对多、多对多注解mappedBy属性的总结

控制台打出的SQL语句:

Hibernate 一对一、一对多、多对多注解mappedBy属性的总结
Hibernate: 
    select
        student0_.student_id as student_1_0_0_,
        student0_.age as age2_0_0_,
        student0_.name as name3_0_0_ 
    from
        student student0_ 
    where
        student0_.student_id=?
Hibernate: 
    select
        teacher0_.teacher_id as teacher_1_1_0_,
        teacher0_.age as age2_1_0_,
        teacher0_.name as name3_1_0_ 
    from
        teacher teacher0_ 
    where
        teacher0_.teacher_id=?
Hibernate: 
    select
        teachers0_.student_id as student_2_2_0_,
        teachers0_.teacher_id as teacher_1_2_0_,
        teacher1_.teacher_id as teacher_1_1_1_,
        teacher1_.age as age2_1_1_,
        teacher1_.name as name3_1_1_ 
    from
        ts_relation teachers0_ 
    inner join
        teacher teacher1_ 
            on teachers0_.teacher_id=teacher1_.teacher_id 
    where
        teachers0_.student_id=?
Hibernate 一对一、一对多、多对多注解mappedBy属性的总结

产生的结果:

Hibernate 一对一、一对多、多对多注解mappedBy属性的总结

----------------------------------------------------------------------------------------

然后,清空数据库,做第四次测试:

Hibernate 一对一、一对多、多对多注解mappedBy属性的总结
public void test1(){
        Student student1 = new Student("学生张三",3);
        Student student2 = new Student("学生李四",4);
        Teacher teacher1 = new Teacher("老师王五",5);
        Teacher teacher2 = new Teacher("老师赵六",6);
    List</span>&lt;Student&gt; students = <span style="color: #0000ff;">new</span> ArrayList&lt;&gt;<span style="color: #000000;">();
    students.add(student1);
    students.add(student2);
    List</span>&lt;Teacher&gt; teachers = <span style="color: #0000ff;">new</span> ArrayList&lt;&gt;<span style="color: #000000;">();
    teachers.add(teacher1);
    teachers.add(teacher2);
    
    
    </span><span style="color: #0000ff;">int</span> stuId = 4<span style="color: #000000;">;
    </span><span style="color: #0000ff;">int</span> teacherId = 6<span style="color: #000000;">;
    Student persistentStudent </span>= (Student)session.get(Student.<span style="color: #0000ff;">class</span><span style="color: #000000;">, stuId); 
    Teacher persistentTeacher </span>= (Teacher)session.get(Teacher.<span style="color: #0000ff;">class</span><span style="color: #000000;">, teacherId);
    persistentTeacher.getStudents().remove(persistentStudent);
    session.update(persistentTeacher);
}</span></pre>
Hibernate 一对一、一对多、多对多注解mappedBy属性的总结

控制台打出的SQL语句:

Hibernate 一对一、一对多、多对多注解mappedBy属性的总结
Hibernate: 
    select
        student0_.student_id as student_1_0_0_,
        student0_.age as age2_0_0_,
        student0_.name as name3_0_0_ 
    from
        student student0_ 
    where
        student0_.student_id=?
Hibernate: 
    select
        teacher0_.teacher_id as teacher_1_1_0_,
        teacher0_.age as age2_1_0_,
        teacher0_.name as name3_1_0_ 
    from
        teacher teacher0_ 
    where
        teacher0_.teacher_id=?
Hibernate: 
    select
        students0_.teacher_id as teacher_1_2_0_,
        students0_.student_id as student_2_2_0_,
        student1_.student_id as student_1_0_1_,
        student1_.age as age2_0_1_,
        student1_.name as name3_0_1_ 
    from
        ts_relation students0_ 
    inner join
        student student1_ 
            on students0_.student_id=student1_.student_id 
    where
        students0_.teacher_id=?
Hibernate: --------------------------注意这条
    delete 
    from
        ts_relation 
    where
        teacher_id=? 
Hibernate: 
    insert 
    into
        ts_relation
        (teacher_id, student_id) 
    values
        (?, ?)
Hibernate 一对一、一对多、多对多注解mappedBy属性的总结

产生的结果:

Hibernate 一对一、一对多、多对多注解mappedBy属性的总结

可见:在Student类的teachers字段的@ManyToMany注解上配置属性mappedBy = "students",所有Student类产生的对象均不能删除和老师的关联关系,只有老师可以。

----------------------------------------------------------------------------------------

 由此证明了之前所说的,mappedBy表示,本类防止控制和另一方的关联关系,所填内容必为本类在另一方的字段名。

注意:mappedBy和@JoinTable是互斥的,也就是说,@"关联关系注解"里面写了mappedBy属性,下面就不能再写@JoinTable。否则,Hibernate报异常。