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();
    }
}

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

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

优质内容筛选与推荐>>
1、回调函数
2、ACM 阶乘数位数
3、sh cssupdate 优化
4、一头雾水中
5、【压测-jmeter】]java请求


长按二维码向我转账

受苹果公司新规定影响,微信 iOS 版的赞赏功能被关闭,可通过二维码转账支持公众号。

    阅读
    好看
    已推荐到看一看
    你的朋友可以在“发现”-“看一看”看到你认为好看的文章。
    已取消,“好看”想法已同步删除
    已推荐到看一看 和朋友分享想法
    最多200字,当前共 发送

    已发送

    朋友将在看一看看到

    确定
    分享你的想法...
    取消

    分享想法到看一看

    确定
    最多200字,当前共

    发送中

    网络异常,请稍后重试

    微信扫一扫
    关注该公众号





    联系我们

    欢迎来到TinyMind。

    关于TinyMind的内容或商务合作、网站建议,举报不良信息等均可联系我们。

    TinyMind客服邮箱:support@tinymind.net.cn