hibernate 一对多的单项关联-表的搭建

班级的映射关系表    
    <?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>
        <class name="cn.itcast.domain.Classess">
            <id name="cid" length="5" type="java.lang.Long">
                <generator class="increment"></generator>
            </id>
            <property name="cname" length="20" type="java.lang.String"></property>
            <property name="description" length="100" type="java.lang.String"></property>
    <!-- 
    set元素对应类中的set集合
    通过set元素使classes表与student表建立关联
       key是通过外键的形式让两张表建立关联
       one-to-many是通过类的形式让两个类建立关联
    cascade 级联
       save-update
       1、当 保存班级的时候,对学生进行怎么样的操作
            如果学生对象在数据库中没有对应的值,这个时候会执行save操作
            如果学生对象在数据库中有对应的值,这个时候会执行update操作
       delete
       all
    inverse  维护关系
       true      不维护关系     
       false     维护关系
       default   false
     -->
             <set name="students" cascade="all" inverse="true">
        <!-- key是用来描述外键-->
                <key>
                    <column name="cid"></column>
                </key>
            <one-to-many class="cn.itcast.domain.Student"/>
            </set>
        </class>
    </hibernate-mapping>
     
   
    学生映射关系表
    <?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>
        <class name="cn.itcast.domain.Student">
            <id name="sid" length="5">
                <generator class="increment"></generator>
            </id>
            <property name="sname" length="20"></property>
            <property name="description" length="100"></property>
        </class>
    </hibernate-mapping>
     
    1.保存班级和学生
    @Test
    public void testSaveClassess(){
        Session session = sessionFactory.openSession();
        Transaction transaction = session.beginTransaction();
        Classess Classess = new Classess();
        Classess.setCname("传智上海云一期");
        Classess.setDescription("很牛");
        session.save(Classess);
        transaction.commit();
        session.close();
    }
    
    @Test
    public void testSaveStudent(){
        Session session = sessionFactory.openSession();
        Transaction transaction = session.beginTransaction();
        Student student = new Student();
        student.setSname("班长");
        student.setDescription("老牛:很牛");
        session.save(student);
        transaction.commit();
        session.close();
    }
    @Test
    public void testSaveClassess_Student(){
    Session session = sessionFactory.openSession();
    Transaction transaction = session.beginTransaction();
    
    Classess Classess = new Classess();
    Classess.setCname("xxx:");
    Classess.setDescription("很牛X");
    
    Student student = new Student();
    student.setSname("班长");
    student.setDescription("老牛:很牛X");
    
    session.save(student);
    session.save(Classess);
     
    transaction.commit();
    session.close();
    }
     
     
 2.cascade-1-保存班级保存学生
1、在classes.hbm.xml文件,针对student进行了级联操作save-update
2、在客户端的代码中,通过班级建立班级与学生之间的关系
3、因为student是一个临时状态的对象
4、在保存班级的时候同时保存学生
 
 
/**
 * 在保存班级的时候,级联保存学生
 */
@Test
public void testSaveClassess_Cascade_Student_Save(){
    Session session = sessionFactory.openSession();
    Transaction transaction = session.beginTransaction();
    
    Classess Classess = new Classess();
    Classess.setCname("xxxxxxxxx2:");
    Classess.setDescription("很牛XX");
    
    Student student = new Student();
    student.setSname("班长");
    student.setDescription("老牛:很牛XX");
    
    Set<Student> students = new HashSet<Student>();
    students.add(student);
    
    //建立Classess与student之间的关联
    Classess.setStudents(students);
    session.save(Classess);
    transaction.commit();
    session.close();
}

@Test
public void testSaveClassess_Cascade_Student_Update(){
    Session session = sessionFactory.openSession();
    Transaction transaction = session.beginTransaction();
    
    Classess Classess = new Classess();
    Classess.setCname("xxxxxxxx4:");
    Classess.setDescription("很牛XXX");
    
    Student student = (Student)session.get(Student.class, 1L);
    
    student.setSname("班秘");
    
    Set<Student> students = new HashSet<Student>();
    students.add(student);
    
    Classess.setStudents(students);
    
    session.save(Classess);
    transaction.commit();
    session.close();
}

@Test
public void testUpdateClassess_Cascade_Student_Save(){
    Session session = sessionFactory.openSession();
    Transaction transaction = session.beginTransaction();
    Classess Classess = (Classess)session.get(Classess.class, 5L);
    Student student = new Student();
    student.setSname("班花");
    student.setDescription("稀有人物");
    Classess.getStudents().add(student);
    transaction.commit();
    session.close();
}
 

 3.cascade-2-保存班级更新学生
@Test
public void testUpdateClassess_Cascade_Student_Update(){
    Session session = sessionFactory.openSession();
    Transaction transaction = session.beginTransaction();
    Classess Classess = (Classess)session.get(Classess.class, 5L);
    Set<Student> students = Classess.getStudents();//为cid为5的班级的所有的学生
    //for(Student student:students){
    //student.setDescription("压力山大");
    //}
    transaction.commit();
    session.close();
}
 
4.更新班级保存或者更新学生-隐式操作异常
在客户端试图通过保存班级保存学生,但是由于在配置文件中针对students没有cascade属性,没有级联,所以导致
classes中的student成为临时状态的对象了,hibernate不允许这种情况出现
把session.save/update一个对象的操作为显示操作,级联对象的操作为隐式操作
 
 
/**
 * 一个错误的演示,映射文件中没有写级联属性
 */
@Test
public void testSaveClassess_Cascade_Student_Save_Error(){
    Session session = sessionFactory.openSession();
    Transaction transaction = session.beginTransaction();
    
    Classess Classess = new Classess();
    Classess.setCname("xxxxxxxx5:");
    Classess.setDescription("很牛XXXXXX");
    
    Student student = new Student();
    student.setSname("班长XXXXXX");
    student.setDescription("老牛:很牛XXXXXX");
    
    Set<Student> students = new HashSet<Student>();
    students.add(student);
    
    //建立Classess与student之间的关联
    Classess.setStudents(students);
    session.save(Classess);
    transaction.commit();
    session.close();
}

5-关系操作 inverse
Classes.hbm.xml
   <set name="students" inverse="true/false/default">
inverse所在的映射文件classes对classes与student之间的关系是否进行维护
  维护关系体现在两点:
     1、在映射文件中inverse的值必须是false/default
     2、必须在客户端代码上建立两者之间的关系
 
/**
 * 已经存在一个班级,新建一个学生,建立学生与班级之间的关系
 *    通过更新班级级联保存学生  cascade
 *    建立班级和学生之间的关系  inverse
 */
@Test
public void testSaveStudent_R_1(){
Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
Student student = new Student();
student.setSname("技术班长");
student.setDescription("大神");
Classess Classess = (Classess)session.get(Classess.class, 1L);

Classess.getStudents().add(student);

transaction.commit();
session.close();
}

/**
 * Hibernate: select Classess0_.cid as cid0_0_, Classess0_.cname as cname0_0_, Classess0_.description as descript3_0_0_ from Classess Classess0_ where Classess0_.cid=?
Hibernate: select max(sid) from Student
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_ from Student students0_ where students0_.cid=?
Hibernate: insert into Student (sname, description, sid) values (?, ?, ?)
更新关系的操作
Hibernate: update Student set cid=? where sid=?
 */
@Test
public void testSaveStudent_R_2(){
    Session session = sessionFactory.openSession();
    Transaction transaction = session.beginTransaction();
    Student student = new Student();
    student.setSname("技术班长");
    student.setDescription("大神");
    Classess Classess = (Classess)session.get(Classess.class, 1L);
    
    session.save(student);
    
    Classess.getStudents().add(student);
    
    transaction.commit();
    session.close();
}

/**
 * 已经存在一个学生,新建一个班级,把学生加入到该班级
 */
@Test
public void testSaveClassess_R(){
    Session session = sessionFactory.openSession();
    Transaction transaction = session.beginTransaction();
    
    Classess Classess = new Classess();
    Classess.setCname("老毕基础加强班");
    Classess.setDescription("必看,杀手锏");
    
    Student student = (Student)session.get(Student.class, 2L);
    Set<Student> students = new HashSet<Student>();
    students.add(student);
    Classess.setStudents(students);
    
    session.save(Classess);
    transaction.commit();
    session.close();
    
 }
 
 
 /**
 * 把一个学生从一个班级转移到另一个班级
 * Hibernate: select Classess0_.cid as cid0_0_, Classess0_.cname as cname0_0_, Classess0_.description as descript3_0_0_ from Classess Classess0_ where Classess0_.cid=?
Hibernate: select Classess0_.cid as cid0_0_, Classess0_.cname as cname0_0_, Classess0_.description as descript3_0_0_ from Classess Classess0_ where Classess0_.cid=?
Hibernate: select student0_.sid as sid1_0_, student0_.sname as sname1_0_, student0_.description as descript3_1_0_ from Student student0_ where student0_.sid=?
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_ from Student students0_ where students0_.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_ from Student students0_ where students0_.cid=?
Hibernate: update Student set cid=null where cid=? and sid=?
Hibernate: update Student set cid=? where sid=?
 */
@Test
public void testTransformClass(){
    Session session = sessionFactory.openSession();
    Transaction transaction = session.beginTransaction();
    //Classess Classess5 = (Classess)session.get(Classess.class, 5L);
    Classess Classess6 = (Classess)session.get(Classess.class, 6L);
    Student student = (Student)session.get(Student.class, 1L);
    //Classess5.getStudents().remove(student);
    Classess6.getStudents().add(student);
    transaction.commit();
    session.close();
}
/**
 * 解除一个班级和一些学生之间的关系
 */

@Test
public void testR_Some(){
    Session session = sessionFactory.openSession();
    Transaction transaction = session.beginTransaction();
    Classess Classess = (Classess)session.get(Classess.class, 1L);
    Set<Student> students = Classess.getStudents();
    //for(Student student:students){
    //if(student.getSid().longValue()==6||student.getSid().longValue()==7){
    //students.remove(student);
    //}
    //}
    //set-->list
    //List<Student> sList = new ArrayList<Student>(students);
    //for(int i=0;i<sList.size();i++){
     //  if(sList.get(i).getSid().longValue()==6||sList.get(i).getSid().longValue()==7){
       //         sList.remove(sList.get(i));
        //        i--;
        //}
    //}

    students = new HashSet<Student>(sList);
    Classess.setStudents(students);
    /**
     * 增强for循环只能修改一次
     *   1、用普通的for循环
     *   2、新建一个set集合,把原来的set集合要保留的数据存放到新的set集合中
     */
    transaction.commit();
    session.close();
}

/*
 * Classess.setStudents(null);直接把班级针对student的集合设置为null
 */
@Test
public void testRealseAll(){
    Session session = sessionFactory.openSession();
    Transaction transaction = session.beginTransaction();
    Classess Classess = (Classess)session.get(Classess.class, 1L);
    //Set<Student> students = Classess.getStudents();
    //students.clear();
    Classess.setStudents(null);
    transaction.commit();
    session.close();
}

/**
 * 已经存在一个班级,已经存在一个学生,建立该班级与该学生之间的关系
 * 11、已经存在一个班级,已经存在多个学生,建立多个学生与班级之间的关系
 */

//cascade=”delete”或”all”
@Test
public void testDeleteStudent(){
    Session session = sessionFactory.openSession();
    Transaction transaction = session.beginTransaction();
    Student student = (Student)session.get(Student.class, 8L);
    session.delete(student);
    transaction.commit();
    session.close();
}
时间: 2024-08-07 00:04:04

hibernate 一对多的单项关联-表的搭建的相关文章

hibernate一对多等情况关联查询效率低的解决方法

方法就是设置lazy=true 其实整个项目在接手时已经搭建好框架,数据库采用的是MySQL.客户运行了一年多时间,速度越来越慢.加上最近新开发的功能,速度已经不能让人接受. 先解决了MySQL远程访问速度问题,效果有了变化,但是依旧不能让人接受.后加功能都是自己亲手建的表,从数据库上杜绝了外键(个人不喜欢),没想到的是之前的表全是外键,而且有很多...设计不合理.废话不多说了,讲一讲改变后和之前的变化.之前页面加载10S,测试得分是0分,伤心的要死.改变之后是1s,得分88分.....好了不多

Hibernate一对多、多对一关联

一对多.多对一关联:在多方加外键 示例:Group(一方)和User(多方),一个Group可以有多个User,每个User只能属于一个Group   多对一单向关联 在User(多方)中建Group(一方)对象,并添加@ManyToOne注解 1.建Group实体类和User实体类,添加Annotation注解,如下 @Entity @Table(name="_group") //group在MySQL中是关键字,不能直接做表名 public class Group { privat

hibernate单项关联

多对一(many to one)单向many-to-one关联是最常见的单向关联关系. <class name="Person"> <id name="id" column="personId"> <generator class="native"/> </id> <many-to-one name="address" column="addr

Hibernate一对多单向关联和双向关联映射方法及其优缺点 (待续)

一对多关联映射和多对一关联映射实现的基本原理都是一样的,既是在多的一端加入一个外键指向一的一端外键,而主要的区别就是维护端不同.它们的区别在于维护的关系不同: 一对多关联映射是指在加载一的一端数据的同时加载多的一端的数据 多对一关联映射是指在加载多的一端数据的同时加载一的一端的数据 而单向一对多关联映射是在一的一端维护关系的,具有以下的缺点: 必须先保存多的一端后才可以保存一的一端,所以在保存多的一端时多的一端不知道一的一端是否 存在相应的数据,所以只能将维护的关系字段设置为null,如果为非空

03.Hibernate一对多关联

前言:在域模型中,类与类之间最普遍的关系就是关联关系,在UML语言中关联关系是有方向的.在数据库中表与表之间也会有关联关系,本节介绍通过Hibernate映射一对多的关联关系,这是一种最普遍的关联关系. 1.数据库表的一对多关联关系 (1)示例数据库表说明 本节使用两张表:tb_student(学生表).tb_class(班级表),一个班级里有多个学生,而一个学生只能在一个班级里,这样构成了学生与班级的多对一关联关系.下图表述了Student与Class之间的关系: (2)使用MySQL创建表

Mysql学生管理系统:表的建立,外键一对多,多对多关系,中间关联表的建立

学生管理系统 管理员注册/登录/注销 注册班级(班级详细信息) 注册学生信息 查看班级信息/查看老师资料 教师注册/注销  查看教师资料  查看学生资料  根据名称/班级/ 查看学生详细信息--支持模糊 注册科目 管理员(admini) ad_id(管理员id)     ad_number(管理员账号) ad_pass(管理员密码)    ad_yn(管理员是否禁用) create table admini( ad_id int PRIMARY KEY AUTO_INCREMENT,-- 主键自

hibernate 一对多关联关系(详细分析)

在领域模型中, 类与类之间最普遍的关系就是关联关系. 在 UML 中, 关联是有方向的. 以 Customer 和 Order 为例: 一个用户能发出多个订单, 而一个订单只能属于一个客户. 从 Order 到 Customer 的关联是多对一关联; 而从 Customer 到 Order 是一对多关联 单向关联 双向关联 单向 n-1 单向 n-1 关联只需从 n 的一端可以访问 1 的一端 域模型: 从 Order 到 Customer 的多对一单向关联需要在Order 类中定义一个 Cus

Hibernate一对多操作

--------------------siwuxie095 Hibernate 一对多操作 以客户和联系人为例,客户是一,联系人是多 即 一个客户里面有多个联系人,一个联系人只能属于一个客户 注意:这里的客户是公司级的,即 公司,联系人 即 公司里的员工 (一)一对多映射配置 第一步:创建两个实体类,客户和联系人 第二步:让两个实体类之间互相表示 (1)在客户实体类中表示多个联系人 (2)在联系人实体类中表示所属客户 第三步:配置映射关系 「一般一个实体类对应一个映射配置文件」 (1)配置基本

Hibernate一对多(多对一)关联关系

上一篇博文总结了 Hibernate 的一对一的关联关系, 包括基于主键的单向一对一, 基于外键的单向一对一, 基于外键的双向一对一. 下面咱们说一下 Hibernate 的一对多关联关系. 其实一对多和多对一是一样的, 一对多反过来想就是多对一了. Hibernate的一对多可分为: 1. 单向一对多. 2. 双向一对多. OneByOne 一: 单向一对多 准备工作: 咱们以 客户(Customer) 和 订单(Order) 的例子来说, 一个客户可以有多个订单, 但是一个订单只能属于一个客