美文网首页
9.hibernate映射(多对多)

9.hibernate映射(多对多)

作者: arkulo | 来源:发表于2017-07-23 21:42 被阅读16次

多对多也是分为:

  • 单向多对多
  • 双向多对多

案例说明:

一个学生可以上多个班级的课,一个班级也可以有多个学生

先来看看实体类

classes.java班级类

    package entity;
    
    import java.util.Set;
    
    /**
     * 这里还是用classes做测试,多对多,也就是一个学生可以在多个班上课,一个班可以有多个学生
     * @author arkulo
     *
     */
    public class Classes {
        private int id;
        private String className;
        private Set<Student> student;
        
        
        
        public int getId() {
            return id;
        }
        public void setId(int id) {
            this.id = id;
        }
        public String getClassName() {
            return className;
        }
        public void setClassName(String className) {
            this.className = className;
        }
        public Set<Student> getStudent() {
            return student;
        }
        public void setStudent(Set<Student> student) {
            this.student = student;
        }
    }

Student.java学生类

    package entity;
    
    public class Student {
        private int id;
        private String name;
    //  private Classes classes;
        
        
    //  public Classes getClasses() {
    //      return classes;
    //  }
    //  public void setClasses(Classes classes) {
    //      this.classes = classes;
    //  }
        public int getId() {
            return id;
        }
        public void setId(int id) {
            this.id = id;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
    }

一、单向多对多

Classes.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="entity">
        <class name="Classes" dynamic-update="true" >
            <id name="id">
                <generator class="native"/>
            </id>
            <property name="className" />
            <set name="student" table="_relation_classes_student">
            <!-- 这里维护一张中间表,student_id关联student表,classes_id关联classes表 -->
                <key column="classes_id"></key>
                <many-to-many class="Student" column="student_id"></many-to-many>
            </set>
        </class>    
    </hibernate-mapping>

这里要仔细注意中间表的写法,table确定表名称,key标签的column属性设置关联classes主键,manytomany标签column属性设置关联student表主键。现在对象之间的关联关系,是由classes维护的,student这边么有维护关系,请看下面的student的映射文件

student.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="entity">
        <class name="Student" dynamic-update="true">
            <id name="id">
                <generator class="native"/>
            </id>
            <property name="name" />
        </class>    
    </hibernate-mapping>

单元测试:
package entity;

    import java.util.HashSet;
    import java.util.Iterator;
    import java.util.Set;
    
    import org.hibernate.classic.Session;
    
    import junit.framework.TestCase;
    import util.hibernateUtil;
    
    /**
     * 单向多对多关联
     * 测试目的:
     * 1. 测试添加
     * 2. 测试查询
     * 3. 测试删除
     * 
     * @author arkulo
     *
     */
    
    public class testManyToMany extends TestCase {
    //  新增,单向,是在classes端维护的关系
        public void test1() {
            Session session = null;
    
            try {
                session = hibernateUtil.getSession();
                session.beginTransaction();
    //          先插入3条学生记录,然后插入班级记录,又插入三条关系表记录
                
                Student st1 = new Student();
                st1.setName("张三");
                Student st2 = new Student();
                st2.setName("李四");          
                Student st3 = new Student();
                st3.setName("王五");  
                session.save(st1);
                session.save(st2);
                session.save(st3);
                
                Set<Student> jihe = new HashSet();
                jihe.add(st1);
                jihe.add(st2);
                jihe.add(st3);
                
                Classes cl = new Classes();
                cl.setClassName("一年级三班");
                cl.setStudent(jihe);
                            
                session.save(cl);
    
                session.getTransaction().commit();
            } catch (Exception e) {
                e.printStackTrace();
                session.getTransaction().rollback();
            } finally {
                hibernateUtil.closeSession(session);
            }
        }
        
        
    //  查询某个班的学生情况
        public void test2()
        {
            Session session = null;
    
            try {
                session = hibernateUtil.getSession();
                session.beginTransaction(); 
    //          这里先发出一个查询班级的sql语句,并打印。当需要用到与班级关联的学生的时候,
    //          系统又发出了一条sql语句,将所有班级学生一起查出来
                Classes cl = (Classes)session.get(Classes.class, 1);
                System.out.println("班级名称:"+cl.getClassName());
                Iterator<Student> it = cl.getStudent().iterator();
                while(it.hasNext())
                {
                    Student student = it.next();
                    System.out.println("学生姓名:"+student.getName());
                }
                
                session.getTransaction().commit();
            } catch (Exception e) {
                e.printStackTrace();
                session.getTransaction().rollback();
            } finally {
                hibernateUtil.closeSession(session);
            }       
        }
        
        
    //  删除班级是否会抛出异常?还是会一起删除学生
        public void test3()
        {
            test1();
            System.out.println("------------------------------------------");
            Session session = null;
    
            try {
                session = hibernateUtil.getSession();
                session.beginTransaction(); 
    //          这里先发出一个查询班级的sql语句,并打印。当需要用到与班级关联的学生的时候,
    //          系统又发出了一条sql语句,将所有班级学生一起查出来
                Classes cl = (Classes)session.get(Classes.class, 1);
                System.out.println("班级名称:"+cl.getClassName());
                Iterator<Student> it = cl.getStudent().iterator();
                while(it.hasNext())
                {
                    Student student = it.next();
                    System.out.println("学生姓名:"+student.getName());
                }
                
    //          这个时候缓存中已经存在班级和所有相关学生的对象缓存,这时候我们删除班级,看是否能一起删除学生数据
    //          实际上,这个操作的sql语句如下:
    //          Hibernate: delete from _relation_classes_student where classes_id=?
    //          Hibernate: delete from Classes where id=?
    //          先删除了关系表中的所有该班级的数据,然后删除了班级表中的数据记录
                session.delete(cl);
                
                session.getTransaction().commit();
            } catch (Exception e) {
                e.printStackTrace();
                session.getTransaction().rollback();
            } finally {
                hibernateUtil.closeSession(session);
            }       
        }   
    }

二、双向多对多

student.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="entity">
        <class name="Student" dynamic-update="true">
            <id name="id">
                <generator class="native"/>
            </id>
            <property name="name" />
            <set name="classes">
                <key column="student_id"></key>
                <many-to-many class="Classes" column="classes_id"></many-to-many>
            </set>
        </class>    
    </hibernate-mapping>

单元测试:

    package entity;
    
    import java.util.HashSet;
    import java.util.Iterator;
    import java.util.Set;
    
    import org.hibernate.classic.Session;
    
    import junit.framework.TestCase;
    import util.hibernateUtil;
    
    /**
     * 双向多对多关联
     * 测试目的:
     * 一个课程班级对应多个学生,一个学生也可以报多个课程班级
     * 1. 测试添加
     * 2. 测试查询
     * 3. 测试删除
     * 
     * @author arkulo
     *
     */
    
    public class testManyToMany extends TestCase {
    //  新增,双向,是在classes端维护的关系
        public void test1() {
            Session session = null;
    
            try {
                session = hibernateUtil.getSession();
                session.beginTransaction();
    //          先插入3条学生记录,然后插入班级记录,又插入三条关系表记录
                
                Student st1 = new Student();
                st1.setName("张三");
                Student st2 = new Student();
                st2.setName("李四");          
                Student st3 = new Student();
                st3.setName("王五");  
                session.save(st1);
                session.save(st2);
                session.save(st3);
    
                Classes cl = new Classes();
                cl.setClassName("音乐班");
                Classes cl1 = new Classes();
                cl1.setClassName("美术班");
                Classes cl2 = new Classes();
                cl2.setClassName("跆拳道班");       
                
    //          上音乐班的学生
                Set<Student> jihe = new HashSet();
                jihe.add(st1);
                jihe.add(st2);
                cl.setStudent(jihe);
    //          上美术班的同学
                Set<Student> jihe1 = new HashSet();
                jihe1.add(st2);
                jihe1.add(st3);
                cl1.setStudent(jihe1);          
    //          上跆拳道班的学生
                Set<Student> jihe2 = new HashSet();
                jihe2.add(st1);
                jihe2.add(st3);
                cl2.setStudent(jihe2);                  
    
                            
                session.save(cl);
                session.save(cl1);
                session.save(cl2);
    
                session.getTransaction().commit();
            } catch (Exception e) {
                e.printStackTrace();
                session.getTransaction().rollback();
            } finally {
                hibernateUtil.closeSession(session);
            }
        }
        
        
    //  查询某个班的学生情况
        public void test2()
        {
            test1();
            System.out.println("------------------------------");
            Session session = null;
    
            try {
                session = hibernateUtil.getSession();
                session.beginTransaction(); 
    //          这里先发出一个查询班级的sql语句,并打印。当需要用到与班级关联的学生的时候,
    //          系统又发出了一条sql语句,将所有班级学生一起查出来
                Classes cl = (Classes)session.get(Classes.class, 1);
                System.out.println("班级名称:"+cl.getClassName());
                Iterator<Student> it = cl.getStudent().iterator();
                while(it.hasNext())
                {
                    Student student = it.next();
                    System.out.println("学生姓名:"+student.getName());
                }
                
                session.getTransaction().commit();
            } catch (Exception e) {
                e.printStackTrace();
                session.getTransaction().rollback();
            } finally {
                hibernateUtil.closeSession(session);
            }       
        }
        
        
    //  删除班级是否会抛出异常?还是会一起删除学生
        public void test3()
        {
            test1();
            System.out.println("------------------------------------------");
            Session session = null;
    
            try {
                session = hibernateUtil.getSession();
                session.beginTransaction(); 
    //          这里先发出一个查询班级的sql语句,并打印。当需要用到与班级关联的学生的时候,
    //          系统又发出了一条sql语句,将所有班级学生一起查出来
                Classes cl = (Classes)session.get(Classes.class, 1);
                System.out.println("班级名称:"+cl.getClassName());
                Iterator<Student> it = cl.getStudent().iterator();
                while(it.hasNext())
                {
                    Student student = it.next();
                    System.out.println("学生姓名:"+student.getName());
                }
                
    //          这个时候缓存中已经存在班级和所有相关学生的对象缓存,这时候我们删除班级,看是否能一起删除学生数据
    //          实际上,这个操作的sql语句如下:
    //          Hibernate: delete from _relation_classes_student where classes_id=?
    //          Hibernate: delete from Classes where id=?
    //          先删除了关系表中的所有该班级的数据,然后删除了班级表中的数据记录
                session.delete(cl);
                
                session.getTransaction().commit();
            } catch (Exception e) {
                e.printStackTrace();
                session.getTransaction().rollback();
            } finally {
                hibernateUtil.closeSession(session);
            }       
        }   
    }

相关文章

  • 9.hibernate映射(多对多)

    多对多也是分为: 单向多对多 双向多对多 案例说明: 一个学生可以上多个班级的课,一个班级也可以有多个学生 先来看...

  • 映射:多对多

  • Hibernate—— 多对多映射

    简介 多对多关联也是常见的一种关联关系,如项目和员工之间就是典型的多对多关系。 ①一个项目可以...

  • hibernate --------多对多映射

    还是用学生和老师来举例子一个老师可以教多个学生,一个学生也可以有多个老师(1)先写老师的实体类package te...

  • Django-关系映射

    关系映射 一对一映射 语法 查询 一对多映射 语法 查询 多对多映射 语法 查询 自定义查询对象

  • 高级映射-多对多查询

    1.需求查询用户及用户购买商品信息 2.思路 将用户信息映射到user中。 在UserBean类中添加订单列表属性...

  • spring data jpa

    一对一 一对多 多对多映射

  • Hibernate—— 一对多映射

    MyEclipse——环境下 映射的类型 1、一对多映射 (one-to-many) 常用 2、多对一映射 (ma...

  • Hibernate 映射关系

    0. 关联关系映射 关联关系映射,是映射关系中比较复杂的一种映射关系,总的说来有一对一、一对多和多对多几种关系。细...

  • 一口一口吃掉Hibernate——多对多关联映射

    今天来说说Hibernate中的多对多关联映射,多对多关联映射涉及到单向映射和双向映射2种。 [java] vie...

网友评论

      本文标题:9.hibernate映射(多对多)

      本文链接:https://www.haomeiwen.com/subject/ubgktxtx.html