hibernate中多对多映射关系

2019-03-28 22:32|来源: 领悟书生

一个用户可以授予多种角色,一种角色可以分配给多个用户。这就是一种多对多的关系。先来看看hibernate中简单的多对多映射关系


管理员的实体类和映射关系

Admin.java

package org.zttc.itat.model;
 
import java.util.Set;
 
public class Admin {
    private int id;
    private String name;
    private Set<Role> roles;
     
    // set get 方法省略
}

Admin.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
 
<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.java

package org.zttc.itat.model;
 
import java.util.HashSet;
import java.util.Set;
 
public class Role {
    private int id;
    private String name;
    private Set<Admin> admins;
    public Role() {
        admins = new HashSet<Admin>();
    }
    public void add(Admin admin) {
        admins.add(admin);
    }
     
    //set get 方法省略
}

Role.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
 
<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>

看看测试类:

package org.zttc.itat.test;
 
import org.hibernate.Session;
import org.junit.Test;
import org.zttc.itat.model.Admin;
import org.zttc.itat.model.Classroom;
import org.zttc.itat.model.Role;
import org.zttc.itat.model.Student;
import org.zttc.itat.util.HibernateUtil;
 
public class TestManyToMany {
    @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);
        }
    }
     
}


使用Many2Many不论在哪一方来维护关系都比较的麻烦,而且很多时候关联表中需要加入其他的属性所以在开发中,经常使用两个一对多来替代多对多


下面的例子是老师与课程之间的多对多关系。

老师的实体及映射

Teacher.java

package org.zttc.itat.model;
 
import java.util.Set;
 
public class Teacher {
    private int id;
    private String name;
    private Set<TeacherCourse> tcs;
    //set get 方法省略
}

Teacher.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
 
<hibernate-mapping package="org.zttc.itat.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>

课程的实体及映射

Course.java

package org.zttc.itat.model;
 
import java.util.Set;
 
public class Course {
    private int id;
    private String name;
    private Set<TeacherCourse> tcs;
    //set get 方法省略
}

Course.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
 
<hibernate-mapping package="org.zttc.itat.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>

老师课程实体及映射

TeacherCourse.java

package org.zttc.itat.model;
 
public class TeacherCourse {
    private int id;
    private double ach;
    private Teacher teacher;
    private Course course;
    //set get 方法省略
}

TeacherCourse.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
 
<hibernate-mapping package="org.zttc.itat.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>

测试类:

public class TestManyToMany2 {
    @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);
        }
    }
     
}


本文链接:hibernate中多对多映射关系,由领悟书生原创(笔记),转载请注明出处http://www.656463.com/article/402

相关问答

更多