ManyToMany(2种解决方案< 1.直接多对多,2.分解成连个oneToMany >)
(1).第一种方式:
实体类:
Admin.java
public class Admin { private int id; private String name; private Set<Role> roles; 省略get,set }
Role.java
public class Role { private int id; private String name; private Set<Admin> admins; 省略get,set }
hbm文件
Admin.hbm.xml
<hibernate-mapping package="org.zttc.itat.model"> <class name="Admin" table="t_admin"> <id name="id"> <generator class="native" /> </id> <property name="name" /> <set name="roles" table="t_admin_role" lazy="extra"> <key column="aid" /> <many-to-many class="Role" column="rid" /> </set> </class> </hibernate-mapping>
Role.hbm.xml
<hibernate-mapping package="org.zttc.itat.model"> <class name="Role" table="t_role"> <id name="id"> <generator class="native" /> </id> <property name="name" /> <set name="admins" table="t_admin_role" lazy="extra"> <key column="rid" /> <many-to-many class="Admin" column="aid" /> </set> </class> </hibernate-mapping>
测试方法:
/* * 使用Many2Many不论在哪一方来维护关系都比较的麻烦,而且很多时候关联表中需要加入其他的属性 * 所以在开发中,经常使用两个一对多来替代多对多 */ @Test public void testAdd01() { Session session = null; try { session = HibernateUtil.openSession(); session.beginTransaction(); Admin a1 = new Admin(); a1.setName("张三"); session.save(a1); Admin a2 = new Admin(); a2.setName("李四"); session.save(a2); Role r1= new Role(); r1.setName("超级管理员"); r1.add(a1); session.save(r1); Role r2 = new Role(); r2.setName("财务管理人员"); r2.add(a1); r2.add(a2); session.save(r2); session.getTransaction().commit(); } catch (Exception e) { e.printStackTrace(); if(session!=null) session.getTransaction().rollback(); } finally { HibernateUtil.close(session); } } @Test public void testLoad01() { Session session = null; try { session = HibernateUtil.openSession(); session.beginTransaction(); Admin a = (Admin)session.load(Admin.class, 1); System.out.println(a.getName()); for(Role r:a.getRoles()) { System.out.println(r.getName()); } session.getTransaction().commit(); } catch (Exception e) { e.printStackTrace(); if(session!=null) session.getTransaction().rollback(); } finally { HibernateUtil.close(session); } }
(2).第二种方式
实体类:
public class Teacher { private int id; private String name; private Set<TeacherCourse> tcs; 省略get,set }
public class Course { private int id; private String name; private Set<TeacherCourse> tcs; 省略get,set }
public class TeacherCourse { private int id; private double ach; private Teacher teacher; private Course course; 省略get,set }
hbm文件
<hibernate-mapping package="org.th.model"> <class name="Teacher" table="t_teacher"> <id name="id"> <generator class="native"/> </id> <property name="name"/> <set name="tcs" lazy="extra" inverse="true"> <key column="tid"/> <one-to-many class="TeacherCourse"/> </set> </class> </hibernate-mapping>
<hibernate-mapping package="org.th.model"> <class name="Course" table="t_course"> <id name="id"> <generator class="native"/> </id> <property name="name"/> <set name="tcs" lazy="extra" inverse="true"> <key column="cid"/> <one-to-many class="TeacherCourse"/> </set> </class> </hibernate-mapping>
<hibernate-mapping package="org.th.model"> <class name="TeacherCourse" table="t_teacher_course"> <id name="id"> <generator class="native"/> </id> <property name="ach"/> <many-to-one name="teacher" column="tid"/> <many-to-one name="course" column="cid"/> </class> </hibernate-mapping>
测试方法:
@Test public void testAdd01() { Session session = null; try { session = HibernateUtil.openSession(); session.beginTransaction(); Teacher t1 = new Teacher(); t1.setName("老张"); session.save(t1); Teacher t2 = new Teacher(); t2.setName("老刘"); session.save(t2); Course c1 = new Course(); c1.setName("数据结构"); session.save(c1); Course c2 = new Course(); c2.setName("计算机组成原理"); session.save(c2); TeacherCourse tc1 = new TeacherCourse(); tc1.setAch(87); tc1.setTeacher(t1); tc1.setCourse(c1); session.save(tc1); tc1 = new TeacherCourse(); tc1.setAch(66); tc1.setTeacher(t1); tc1.setCourse(c2); session.save(tc1); tc1 = new TeacherCourse(); tc1.setAch(190); tc1.setTeacher(t2); tc1.setCourse(c1); session.save(tc1); tc1 = new TeacherCourse(); tc1.setAch(20); tc1.setTeacher(t2); tc1.setCourse(c2); session.save(tc1); session.getTransaction().commit(); } catch (Exception e) { e.printStackTrace(); if(session!=null) session.getTransaction().rollback(); } finally { HibernateUtil.close(session); } } @Test public void testLoad01() { Session session = null; try { session = HibernateUtil.openSession(); session.beginTransaction(); Teacher t = (Teacher)session.load(Teacher.class, 1); //load的时候由于延迟加载,会根据不同的情况取相应的关联对象,所以会发出大量的sql /** * 总体来说:最佳实践就是,一般不使用双向关联,特别不建议使用一的这一方的关联 * 因为从一的这一端取关联对象很有可能会涉及到分页操作,所以基本不会使用 * 在设计的时候不是特殊情况不要使用双向关联。 */ System.out.println(t.getName()); for(TeacherCourse tc:t.getTcs()) { System.out.println(tc.getCourse().getName()+":"+tc.getAch()); } session.getTransaction().commit(); } catch (Exception e) { e.printStackTrace(); if(session!=null) session.getTransaction().rollback(); } finally { HibernateUtil.close(session); } }