9.hibernate映射(多对多)

多对多也是分为:

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

案例说明:

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

先来看看实体类

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);
            }       
        }   
    }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,961评论 5 473
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,444评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 148,009评论 0 333
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,082评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,101评论 5 363
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,271评论 1 278
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,738评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,395评论 0 255
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,539评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,434评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,481评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,160评论 3 317
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,749评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,816评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,038评论 1 256
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,548评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,140评论 2 341

推荐阅读更多精彩内容