Hibernate单向多对一映射下的增删改查

Hibernate单向多对一映射下的增删改查


注:作为初学者,本文仅为了巩固自己学习的知识亦或帮助初学者,如有缺漏,请见谅

在软件开发中,类与类之间最普遍的关系就是关联关系,而且关联关系是有方向的。以Student类和Grade类为例,一个年级包含多个学生,一个学生只对应一个年级,从Student到Grade就是多对一映射,从Grade到Student到Student就是一对多映射,同时包含两种关联关系就是双向多对一关系。本文仅介绍单向多对一映射关系。

一、配置单向多对一映射关系
以Student和Grade的关联关系为例,那么该如何来配置呢?既然一个Student只属于一个Grade,所以在Student持久类中应该定义一个Grade的对象;然后在映射文件中配置,下面详细介绍

1. 首先在Student类中定义一个Grade类的对象
  1. public class Student implements Serializable{  
  2.     private int id;  
  3.     private int age;  
  4.     private String name;  
  5.     private Grade grade;  
  6.     //...  
  7. }  
2. 配置映射文件
  1. <hibernate-mapping package="com.wzj.entity">  
  2.     <class name="Student" table="Student">  
  3.         <id name="id" type="java.lang.Integer" column="id">  
  4.             <generator class="assigned"></generator>  
  5.         </id>  
  6.         <property name="name" type="java.lang.String" column="name"></property>  
  7.         <property name="age" type="java.lang.Integer" column="age"></property>  
  8.         <!-- 此句是关键 -->  
  9.         <many-to-one name="grade" class="Grade" column="gradeid"></many-to-one>  
  10.     </class>  
  11.     <!--省去Grade映射-->  
  12. </hibernate-mapping>  
二、单向多对一关系的使用
1.
我们首先创建两个Student对象,1个Grade对象,并建立关系,那么我们该以什么样的顺序来保存呢?
  1. public static void main(String[] args) {  
  2.         Session session=HibernateUtil.currentSession();  
  3.         Transaction tx=session.beginTransaction();  
  4.           
  5.         testCreate(session);  
  6.           
  7.         tx.commit();  
  8.         HibernateUtil.closeSession();  
  9.           
  10.     }  
  11.     public static void testCreate(Session session){  
  12.         Student s1=new Student(1,20,"student-1");  
  13.         Student s2=new Student(2,20,"student-2");  
  14.         Grade g=new Grade(1,"一年级");  
  15.         s1.setGrade(g);  
  16.         s2.setGrade(g);  
  17.           
  18.         //先保存“1”的一方,再保存“n”的一方  
  19.         session.save(g);  
  20.         session.save(s1);  
  21.         session.save(s2);  
  22.     }  
然后运行,数据库中成功更新,控制台输出了3条insert语句,一条插入Grade,2条插入Student。再来看,先保存n的一方:

  1. public static void testCreate(Session session){  
  2.         Student s1=new Student(3,20,"student-3");  
  3.         Student s2=new Student(4,20,"student-4");  
  4.         Grade g=new Grade(2,"二年级");  
  5.         s1.setGrade(g);  
  6.         s2.setGrade(g);  
  7.           
  8.         //先保存“n”的一方,再保存“1”的一方  
  9.         session.save(s1);  
  10.         session.save(s2);  
  11.         session.save(g);  
  12.     }  
然后运行,数据库成功更新,不过这次控制台输出了6条sql语句,第一条是查询年级是否存在,第2、3、4条是插入学生和年级,最后两条是更新学生的GradeId

小结:当我们先插入Student的时候,还要对应插入Grade的ID,此时数据库中并不存在这个Id,所以,Hibernate会先为我们插入一个空值(当然,数据库中的GradeId得允许为空),然后插入Grade之后再根据此时生成的GradeId去更新学生的信息;由此可见,这种方式增加了对数据库的访问频率,降低了程序的性能,所以推荐大家尽量少使用这种方式。

2.查
如下代码:
  1. public static void testQuery(Session session){  
  2.         Student s=(Student)session.get(Student.class1);  
  3.         System.out.println(s.getName());  
  4.     }  
运行发现只是发送了一条sql语句,与之关联的Grade对象并没有查询;假如再加上一句:
  1. Grade g=s.getGrade();  
  2.         System.out.println(g.getGradeName());  
此时再次运行就会发现变成了两条sql语句。倘若我们这样:
  1. public static void testQuery(Session session){  
  2.         Student s=(Student)session.get(Student.class1);  
  3.         System.out.println(s.getName());  
  4.         session.close();  
  5.         Grade g=s.getGrade();  
  6.         System.out.println(g.getGradeId());  
  7.         System.out.println(g.getGradeName());  
  8.     }  
然后会发现,程序在执行g.getGradeName()的时候抛出了一个叫做LazyInitializationException的异常(为什么可以获取到Grade.GradeId呢?)其实这个异常就是Hibernate中常见的懒加载机制异常。


小结:当我们查询“n”的一方时,默认情况下只会查询到n的一方的对象,而与之关联的对象并不会查询,这就是Hibernate中的懒加载(延迟加载)机制。当我们需要使用到关联对象的属性的时候,Hibernate才会发送对应的sql语句去查询并实例化Grade,在实例化之前Grade只是一个代理对象,仅仅拥有一个和Student关联的属性值(GradeId),而其他属性统统无值,关于懒加载的详解,这里有一篇不错的 文章,大家可以参考一下:http://blog.csdn.net/sanjy523892105/article/details/7071139

3.改、删
对于这两种情况来说,使用起来就比较简单了,没有什么特别之处。
需要注意的是:执行删除时,在不设定级联的情况下,并且“1”的一方有“n”的一方在引用的时候,不能直接删除“1”这一方的对象。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值