hibernate多表操作之一对多的单项操作

来源:互联网 发布:泉州师范学院软件学院 编辑:程序博客网 时间:2024/05/22 09:25

hibernate最终还是在最底层生成sql语句来操作数据库

一对多的单项:


实例:班级中有多个学生,班级能找到学生,班级中放入一个集合装学生,学生不能找到班级
          持久化类:Classes 班级,一个班级有多个学生,通过集合来建立关系
 view plain copy
  1. public class Classes implements Serializable{
     private Long cid; //标示符属性
     private String name;  //一般属性
     private String description;
     
     private Set<Student> students;  //关联对象
        
         持久化类:Student  学生

[持久化类]
public class Student implements Serializable{
 private Long sid;
 private String name;
 private String description;
 view plain 
cop

 
      映射文件:Classes.hbm.xml
                        该映射配置文件中重点注意set属性,该属性主要是针对Classes类中的Set集合属性,在映射配置文件中指定这个属性
                        外键:就是在Classes.hbm.xml的配置文件中指定一个属性作为student表中的外键,即:在student表中增加一个表字段(列)cid
                        外键的作用:告诉hibernate怎么样生成sql语句,另外获得查询Classes的时候,同时要获得学生信息,代码怎么实现?
                      
                         指定类与类之间的联系,告诉hibernate客户端Classes联系的是那个Student,告诉hibernate,Classes类中的set集合中存放的是哪个元素
                         因为hibernate出现前还没出现泛型
                        <one-to-many class="com.itheima12.hibernate.domain.Student"/>

<hibernate-mapping>
 <class name="com.itheima12.hibernate.domain.Classes">
  <id name="cid" length="5">
   <generator class="increment"></generator>
  </id>
  <property name="description" length="50"></property>
  <property name="name" length="20"></property>
  <!--
   set元素针对的就是Classes类中的Set属性
   cascade  级联操作
      null  默认值
      save-update
          在保存classes对象的时候,针对student进行保存或者更新的操作
          在更新classes对象的时候,针对student进行保存或者更新的操作
      all
      delete
   inverse  关系操作
      default:classes维护classes与student之间的关系
      true:   classes
不维护classes与student之间的关系,不会生成外键
 
     false:  classes维护classes与student之间的关系
   -->
  <set name="students" cascade="save-update" inverse="true">
   <!--
    外键
        告诉hibernate,通过cid就可以建立classes与student之间的关联
    -->
   <key>
    <column name="cid"></column>
   </key>
   <!--
    告诉hibernate,Classes类中的set集合中存放的是哪个元素
    -->
   <one-to-many class="com.itheima12.hibernate.domain.Student"/>
  </set>
 </class>
</hibernate-mapping>

 
映射文件:Classes.hbm.xml
[html] view plain copy
<hibernate-mapping>
 <class name="com.itheima12.hibernate.domain.Student">
  <id name="sid" length="5">
   <generator class="increment"></generator>
  </id>
  <property name="description" length="50"></property>
  <property name="name" length="20"></property>
 </class>
</hibernate-mapping>
客户端的操作:保存Classes的同时保存学生,注意:通过session只保存了Classes,保存student是hibernate内部保存,称为隐式保存
      为什么student也能够保存?
      我们在Classes.hbm.xml中set元素中建立两个类的联系时候,设置了级联操作cascade="save-update"
      save-update
          在保存classes对象的时候,针对student进行保存或者更新的操作
          在更新classes对象的时候,针对student进行保存或者更新的操作

方式二:可以不设置级联操作,先保存Classes,获取cid,new student(),把cid
     



 /**
  * 在保存班级的时候,级联保存学生
  */
 @Test
 public void testSaveClasses_Cascade_Save_Student(){
  Session session = sessionFactory.getCurrentSession();
  Transaction transaction = session.beginTransaction();
  Classes classes = new Classes();
  classes.setName("黑马视频班");
  classes.setDescription("野牛");
  
  Student student = new Student();
  student.setName("班秘");
  student.setDescription("凤姐");
  
  //建立classes与student之间的关联
  Set<Student> students = new HashSet<Student>();
  students.add(student);
  classes.setStudents(students);
  
  session.save(classes); //显示保存,把保存student称为隐式保存
  transaction.commit();
 }
hibernate产生的sql语句

注意:对于保存一的一方级联保存多的情况,下面insert sql语句,两张表的基本数据插入插入数据库,外键并没有在插入student表数据的时候插入数据库中,而后面通过更新update Student表,把cid外键放入Student表中
如果在一对多双向,通过保存多的一方student级联保存Classes,不需要后面的update,直接将外键cid插入student表中,少了条sql语句,所以说保存学生,即:一对多的双向关联,保存多的一方,在多的一方维护关系更好


hibernate出现时候还没泛型,如果hibernate没有告诉的话,Classes联系哪个Student

hibernate报的一个错误



一个对象引用(references)没有保存的临时状态的实例,在flushing之前保存一个临时状态的对象

错误解析:transient短暂的,临时的·

     在flushing之前,保存一个临时状态的对象

原因:这是在Classes.hbm.xml文件中set元素中去掉  cascade="save-update"

在客户端建立Classes与Student建立关系,意思是保存Classes的同时也要保存Student


 所以hibernate在保存classes的时候,就不知道该怎么办了。



inverse属性

 inverse指的是关系操作,针对的就是外键

inverse  关系操作
  default:classes维护classes与student之间的关系
  true:   classes不维护classes与student之间的关系
  false:  classes维护classes与student之间的关系


当上面在Classes.hbm.xml文件中set元素中设置inverse=true,那么保存Classes 和student时候,Student表中没有外键cid的值

   如果在Classes.hbm.xml文件中,inverse没有写,默认classes维护classes与student之间的关系

           所以发出了更新关系的update语句

    update

        Student

    set

        cid=?

    where

        sid=?     这句语句是产生Student中的外键cid的值,inversedefault/false


怎样同时操作两张表,同时把数据保存到数据库中

       重点注意:映射文件设置级联的情况,必须在客户端建立两个类之间的关联,比如:保存classes的时候同时保存student,就要把student添加到Classes这个类的set集合属性中

1、对于一对多的数据保存在班级一方的映射文件的set元素中   cascade="save-update" 级联保存和更新, 注意级联并不维护外键,即不会为学生表保存外键值,外键需要inverse=“false”维护
      在客户端的代码

/**
  * 在保存班级的时候,级联保存学生
  */
 @Test
 public void testSaveClasses_Cascade_Save_Student(){
  Session session = sessionFactory.getCurrentSession();
  Transaction transaction = session.beginTransaction();
  Classes classes = new Classes();
  classes.setName("黑马视频班");
  classes.setDescription("野牛");
  
  Student student = new Student();
  student.setName("班秘");
  student.setDescription("凤姐");
  
  //建立classes与student之间的关联
  Set<Student> students = new HashSet<Student>();
  students.add(student);
  classes.setStudents(students);
  
  session.save(classes); //显示保存,把保存student称为隐式保存
  transaction.commit();
 }


 
2、
0 0
原创粉丝点击