• hibernate的映射关系之多对一


    接上篇

    为了实现  从  student 端操作增加了字段  classes

    package cn.itcast.hiberate.sh.domain;
    
    import java.io.Serializable;
    
    public class Student implements Serializable{
        private Long sid;
        private String sname;
        private String description;
        
        private Classes classes;
        public Classes getClasses() {
            return classes;
        }
        public void setClasses(Classes classes) {
            this.classes = classes;
        }
        public Long getSid() {
            return sid;
        }
        public void setSid(Long sid) {
            this.sid = sid;
        }
        public String getSname() {
            return sname;
        }
        public void setSname(String sname) {
            this.sname = sname;
        }
        public String getDescription() {
            return description;
        }
        public void setDescription(String description) {
            this.description = description;
        }
        @Override
        public String toString() {
            return "Student [sid=" + sid + ", sname=" + sname + ", description="
                    + description + "]";
        }
        
    }

    Student 的映射文件 作相应修改

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
    <hibernate-mapping>
        <!-- name的值代表的是一个实体 -->
        <class name="cn.itcast.hiberate.sh.domain.Student">
            <!-- id用于指定主键  column,主键在数据库表列 ,  increment,主键自增 -->
            <!-- length,指定长度 type,类型,也可以不写 -->
            <id name="sid" length="5" type="java.lang.Long">
                <generator class="increment"></generator>
            </id>
            <!-- 表示表中普通的属性 -->
            <property name="sname" length="20" type="java.lang.String"></property>
            <property name="description" length="100" type="java.lang.String"></property>
            <!-- column 是指的外键 -->
            <many-to-one name="classes" class="cn.itcast.hiberate.sh.domain.Classes" column="cid" cascade="save-update"></many-to-one>
        </class>
    </hibernate-mapping>

    测试类

    package cn.itcast.hibernate.sh.test;
    
    import java.util.HashSet;
    import java.util.Set;
    
    import org.hibernate.Session;
    import org.hibernate.Transaction;
    import org.junit.Test;
    
    import cn.itcast.hiberate.sh.domain.Classes;
    import cn.itcast.hiberate.sh.domain.Student;
    import cn.itcast.hibernate.sh.utils.HibernateUtils;
    
    public class TestManyToOne extends HibernateUtils{
        static{
            url="/hibernate.cfg.xml";
        }
        // 新建班级的时候同时新建学生
        /**
         *  Hibernate: select max(sid) from Student
            Hibernate: select max(cid) from Classes
            Hibernate: insert into Classes (cname, description, cid) values (?, ?, ?)
            Hibernate: insert into Student (sname, description, cid, sid) values (?, ?, ?, ?)
         */
        // 注意  : 相比于  一对多 ,此时多对一的操作并没有发出 update 语句 
        // 当一对多  时操作的是classes hibernate 会查看两个表,这是外键是在student表中,
        //会通过外键  cid 自动的维护两个表之间的关系,发出 update 语句
        // 当多对一时 外键本身就在 student 表中 ,操作的是 student,会直接维护相应的关系 
        // 所以通过 操作多的一方能达到一定的优化效果
        @Test
        public void test_saveStudent_cascade_saveClasses(){
            Session session = sessionFactory.openSession();
            Transaction transaction = session.beginTransaction();
            Classes classes = new Classes();
            classes.setCname("峡谷3");
            classes.setDescription("召唤师峡谷3");
            Student student = new Student();
            student.setSname("黄金");
            student.setDescription("不错了");
            student.setClasses(classes);    // 多对一的时候这样操作了
            session.save(student);
            transaction.commit();
            session.close();
        }
        // 已经存在一个学生,新建一个班级
        /**
         *  Hibernate: select student0_.sid as sid1_0_, student0_.sname as sname1_0_, 
         *  student0_.description as descript3_1_0_, student0_.cid as cid1_0_ from Student student0_ where student0_.sid=?
            Hibernate: select max(cid) from Classes
            Hibernate: insert into Classes (cname, description, cid) values (?, ?, ?)
            Hibernate: update Student set sname=?, description=?, cid=? where sid=?
         */
        @Test
        public void test_existStudent_saveClasses(){
            Session session = sessionFactory.openSession();
            Transaction transaction = session.beginTransaction();
            Student student = (Student) session.get(Student.class, 5L);
            Classes classes = new Classes();
            classes.setCname("峡谷4");
            classes.setDescription("召唤师峡谷4");
            // 建立两个表的关系
            student.setClasses(classes);
            transaction.commit();
            session.close();
        }
        //已经存在一个班级,新建一个学生,建立学生与班级之间的关系
        /**
         *  Hibernate: select classes0_.cid as cid0_0_, classes0_.cname as cname0_0_, classes0_.description as descript3_0_0_ from Classes classes0_ where classes0_.cid=?
            Hibernate: select max(sid) from Student
            Hibernate: insert into Student (sname, description, cid, sid) values (?, ?, ?, ?)
         */
        /**
         *  Hibernate: select classes0_.cid as cid0_0_, classes0_.cname as cname0_0_, 
         *  classes0_.description as descript3_0_0_ from Classes classes0_ where classes0_.cid=?
            Hibernate: select students0_.cid as cid0_1_, students0_.sid as sid1_, 
            students0_.sid as sid1_0_, students0_.sname as sname1_0_, students0_.description
             as descript3_1_0_, students0_.cid as cid1_0_ from Student students0_ where students0_.cid=?
            Hibernate: select max(sid) from Student
            Hibernate: insert into Student (sname, description, cid, sid) values (?, ?, ?, ?)
            Hibernate: update Student set cid=? where sid=?
         */
        /**
         *  操作 classes 来建立两个表的关系,但是保存的是student 这时也能完成目标,不过会发出update 语句
         *  这时可以看出 classes.getStudents().addAll(students);//在hibernate内部查看的是classes.hbm.xml
            
            session.save(student);//在hibernate内部查看的是Student.hbm.xml
         */
        @Test
        public void test_existClasses_saveStudent(){
            Session session = sessionFactory.openSession();
            Transaction transaction = session.beginTransaction();
            Classes classes = (Classes) session.get(Classes.class, 6L);
            Student student = new Student();
            student.setSname("黄金1");
            student.setDescription("挺好的");
            // 建立两个表的关系
            //student.setClasses(classes);  // 将其注释另外测试,通过classes建立联系,保存的还是 student
            Set<Student> students = new HashSet<Student>();
            students.add(student);
            classes.getStudents().addAll(students);
            session.save(student);
            transaction.commit();
            session.close();
        }
        //把一个学生从一个班级转移到另一个班级
        /**
         *  Hibernate: select student0_.sid as sid1_0_, student0_.sname as sname1_0_, 
         *  student0_.description as descript3_1_0_, student0_.cid as cid1_0_ from Student student0_ where student0_.sid=?
            Hibernate: select classes0_.cid as cid0_0_, classes0_.cname as cname0_0_, 
            classes0_.description as descript3_0_0_ from Classes classes0_ where classes0_.cid=?
            Hibernate: update Student set sname=?, description=?, cid=? where sid=?
    
         */
        @Test
        public void testTransform(){
            Session session = sessionFactory.openSession();
            Transaction transaction = session.beginTransaction();
            Student student = (Student) session.get(Student.class, 6L);
            Classes classes = (Classes) session.get(Classes.class, 5L);
            student.setClasses(classes);
            transaction.commit();
            session.close();
        }
        // 解除某个学生与班级的关系
        /**
         *  Hibernate: select student0_.sid as sid1_0_, student0_.sname as sname1_0_, 
         *  student0_.description as descript3_1_0_, student0_.cid as cid1_0_ from Student student0_ where student0_.sid=?
            Hibernate: update Student set sname=?, description=?, cid=? where sid=?
         */
        @Test
        public void testRelease(){
            Session session = sessionFactory.openSession();
            Transaction transaction = session.beginTransaction();
            Student student = (Student) session.get(Student.class, 6L);
            
            student.setClasses(null);
            transaction.commit();
            session.close();
        }
    }

     多对一,其实相当于是另一个方向的一对多

     而一对多,从多的一端维护关系效率比较高

  • 相关阅读:
    关于scanf、getchar、getch、getche缓冲区分析——C语言
    堆排序(大顶堆、小顶堆)----C语言
    预处理命令使用详解----#if、#endif、#undef、#ifdef、#else、#elif
    参数传递---关于数组的退化
    控制台API函数----HANDLE、SetConsoleCursorPosition、SetConsoleTextAttribute
    二叉树的遍历(前序、中序、后序、已知前中序求后序、已知中后序求前序)
    Fiddler 插件开发,使用 WPF 作为 UI 控件
    从程序集加载类型,遇到 ReflectionTypeLoadException 的处理办法
    如何将应用程序与文件类型(文件扩展名)关联起来?
    为什么 WPF 的 Main 方法需要标记 STAThread 。
  • 原文地址:https://www.cnblogs.com/hello001/p/6813810.html
Copyright © 2020-2023  润新知