美文网首页
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映射(多对多)

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