Hibernate多对多关联关系的使用

来源:互联网 发布:雅克比矩阵简单解释 编辑:程序博客网 时间:2024/06/04 18:59

多对多关系的使用:

Student.hbm.xml

<class name="model.Student" table="student"

       select-before-update="true"><!--把类和数表关联起来-->

       <id name="id" unsaved-value="null"><!--id的产生方式是uuid.hex-->

           <generator class="uuid.hex" />

       </id>

       <property name="cardId" type="string" /><!--映射号-->

       <property name="name" type="string" /><!--映射学生名-->

       <property name="age" type="int" /><!--映射学生岁数-->

       <set name="courses" table="student_course"

           cascade="none">

           <key column="stu_id" />

           <many-to-many class="model.Course"

              column="course_id" />

       </set>

    </class>

Course.hbm.xml

<class name="model.Course" table="course"

       select-before-update="true"><!--把类和数表关联起来-->

       <id name="id" unsaved-value="null" ><!--id的产生方式是uuid.hex-->

           <generator class="uuid.hex" />

       </id>

      

       <property name="name" type="string" /><!--映射课程名-->

      

       <set name="students" table="student_course"

           cascade="save-update">

           <key column="course_id" />

           <many-to-many class="model.Student"

              column="stu_id" />

       </set>

    </class>

多对多关系需要配置的属性比较多,需要记住一个原则:<key column=””>总是和本身类的主键id相对应,而<column=””>总是和关联类的主键id相对应。对于上面的Student.hbm.xml,他有个关联类course<key column=””>对应本身类,而本身类是student,所以应该填写stu_id<column=””>对应关联类,关联类是Course,所以应该填写course_id。通过取得student对象而取得course对象集合的过程:首先取得student对象的主键值id,查找student.hbm.xml,根据“stu_id”找出相对应的“course_id”值,然后再去查找course.hbm.xml,找出course中对应的列名,然后根据“course_id”值在course表中找出相对应的集合。

 

添加关联关系

测试类:看某个学生的选课情况,

Student student = (Student)session.get(Student.class, "5abfe4c705ca8ee00105ca8ee42b0001");

           List list = new ArrayList(student.getCourses());

           for(int i = 0;i<list.size();i++){

              Course course2 = (Course)list.get(i);

              System.out.println(course2.getName());

           }

          

控制台输出:

l  Hibernate: select student0_.id as id0_0_, student0_.cardId as cardId0_0_, student0_.name as name0_0_, student0_.age as age0_0_ from student student0_ where student0_.id=?

l  Hibernate: select courses0_.stu_id as stu1_1_, courses0_.course_id as course2_1_, course1_.id as id2_0_, course1_.name as name2_0_ from student_course courses0_ left outer join course course1_ on courses0_.course_id=course1_.id where courses0_.stu_id=?

l  computer

l  history

l  music

现在该学生还想添加ecnomic课程,对于程序员来说只是为该学生添加了一个到ecnomic 的惯量,具体地说就是在student_course表中新添了一条记录,而studentcourse表都不用变更。

测试类:

session = HibernateUtil.currentSession(); //开启连接

           tx = session.beginTransaction(); //开启事务

           stu=(Student) session.createQuery("from Student s where s.name ='tomclus'").uniqueResult();

           course=(Course) session.createQuery("from Course c where c.name='ecnomic'").uniqueResult();

           stu.getCourses().add(course);

           course.getStudents().add(stu);

 

控制台输出:

l  Hibernate: select student0_.id as id0_, student0_.cardId as cardId0_, student0_.name as name0_, student0_.age as age0_ from student student0_ where student0_.name='tomclus'

l  Hibernate: select course0_.id as id2_, course0_.name as name2_ from course course0_ where course0_.name='ecnomic'

l  Hibernate: select courses0_.stu_id as stu1_1_, courses0_.course_id as course2_1_, course1_.id as id2_0_, course1_.name as name2_0_ from student_course courses0_ left outer join course course1_ on courses0_.course_id=course1_.id where courses0_.stu_id=?

l  Hibernate: select students0_.course_id as course2_1_, students0_.stu_id as stu1_1_, student1_.id as id0_0_, student1_.cardId as cardId0_0_, student1_.name as name0_0_, student1_.age as age0_0_ from student_course students0_ left outer join student student1_ on students0_.stu_id=student1_.id where students0_.course_id=?

l  Hibernate: insert into student_course (stu_id, course_id) values (?, ?)

l  Hibernate: insert into student_course (course_id, stu_id) values (?, ?)

l  ERROR [main] (JDBCExceptionReporter.java:78) - Duplicate entry '5abfe4c705ca8ee00105ca8ee42b0001-

第一句:执行hql语句记载student对象

第二句:执行hql语句加载course对象

第三句:通过辅助表左外连接取得student关联的所有课程

第四句:通过辅助表左外连接取得course关联的所有课程

第五句:由stu.getCourses().add(course);语句引入的插入语句

第六句:由course.getStudents().add(stu);语句引入的插入语句

第七句:抛出异常,第二次插入内容和第一次相同

由此可见,在多对多关系中,如果双方都有控制权(也就是双方都没有设置inverse=true”),则双方都要把关联关系反应到数据库,因此才会有第五和第六条语句,插入的内容相同,导致违反数据库主键约束。

解决方法:

(1)在course.getStudents().add(stu); stu.getCourses().add(course)中只选择一条执行

(2)在某一方设置inverse=”true”,然后再执行语句时使用主控方进行操作(也就是没有inverse=true”的哪一方)

原创粉丝点击