Hibernate单向多对一映射下的增删改查
注:作为初学者,本文仅为了巩固自己学习的知识亦或帮助初学者,如有缺漏,请见谅
在软件开发中,类与类之间最普遍的关系就是关联关系,而且关联关系是有方向的。以Student类和Grade类为例,一个年级包含多个学生,一个学生只对应一个年级,从Student到Grade就是多对一映射,从Grade到Student到Student就是一对多映射,同时包含两种关联关系就是双向多对一关系。本文仅介绍单向多对一映射关系。
一、配置单向多对一映射关系
以Student和Grade的关联关系为例,那么该如何来配置呢?既然一个Student只属于一个Grade,所以在Student持久类中应该定义一个Grade的对象;然后在映射文件中配置,下面详细介绍
1.
首先在Student类中定义一个Grade类的对象
- public class Student implements Serializable{
- private int id;
- private int age;
- private String name;
- private Grade grade;
- //...
- }
- <hibernate-mapping package="com.wzj.entity">
- <class name="Student" table="Student">
- <id name="id" type="java.lang.Integer" column="id">
- <generator class="assigned"></generator>
- </id>
- <property name="name" type="java.lang.String" column="name"></property>
- <property name="age" type="java.lang.Integer" column="age"></property>
- <!-- 此句是关键 -->
- <many-to-one name="grade" class="Grade" column="gradeid"></many-to-one>
- </class>
- <!--省去Grade映射-->
- </hibernate-mapping>
1.
增
我们首先创建两个Student对象,1个Grade对象,并建立关系,那么我们该以什么样的顺序来保存呢?
- public static void main(String[] args) {
- Session session=HibernateUtil.currentSession();
- Transaction tx=session.beginTransaction();
- testCreate(session);
- tx.commit();
- HibernateUtil.closeSession();
- }
- public static void testCreate(Session session){
- Student s1=new Student(1,20,"student-1");
- Student s2=new Student(2,20,"student-2");
- Grade g=new Grade(1,"一年级");
- s1.setGrade(g);
- s2.setGrade(g);
- //先保存“1”的一方,再保存“n”的一方
- session.save(g);
- session.save(s1);
- session.save(s2);
- }
- public static void testCreate(Session session){
- Student s1=new Student(3,20,"student-3");
- Student s2=new Student(4,20,"student-4");
- Grade g=new Grade(2,"二年级");
- s1.setGrade(g);
- s2.setGrade(g);
- //先保存“n”的一方,再保存“1”的一方
- session.save(s1);
- session.save(s2);
- session.save(g);
- }
小结:当我们先插入Student的时候,还要对应插入Grade的ID,此时数据库中并不存在这个Id,所以,Hibernate会先为我们插入一个空值(当然,数据库中的GradeId得允许为空),然后插入Grade之后再根据此时生成的GradeId去更新学生的信息;由此可见,这种方式增加了对数据库的访问频率,降低了程序的性能,所以推荐大家尽量少使用这种方式。
2.查
如下代码:
- public static void testQuery(Session session){
- Student s=(Student)session.get(Student.class, 1);
- System.out.println(s.getName());
- }
- Grade g=s.getGrade();
- System.out.println(g.getGradeName());
- public static void testQuery(Session session){
- Student s=(Student)session.get(Student.class, 1);
- System.out.println(s.getName());
- session.close();
- Grade g=s.getGrade();
- System.out.println(g.getGradeId());
- System.out.println(g.getGradeName());
- }
小结:当我们查询“n”的一方时,默认情况下只会查询到n的一方的对象,而与之关联的对象并不会查询,这就是Hibernate中的懒加载(延迟加载)机制。当我们需要使用到关联对象的属性的时候,Hibernate才会发送对应的sql语句去查询并实例化Grade,在实例化之前Grade只是一个代理对象,仅仅拥有一个和Student关联的属性值(GradeId),而其他属性统统无值,关于懒加载的详解,这里有一篇不错的 文章,大家可以参考一下:http://blog.csdn.net/sanjy523892105/article/details/7071139
3.改、删
对于这两种情况来说,使用起来就比较简单了,没有什么特别之处。
需要注意的是:执行删除时,在不设定级联的情况下,并且“1”的一方有“n”的一方在引用的时候,不能直接删除“1”这一方的对象。