J2EE系列之Hibernate4学习笔记(七)--Session常用方法

来源:互联网 发布:tc21弓坯淘宝 编辑:程序博客网 时间:2024/06/16 09:56

hibernate对于数据的处理使用的都是session中的方法。Session中常用的方法包括:

一、save()方法,这个方法应该已经非常熟悉了,它能把对象又临时状态转变成持久化状态。

1.复制工程Hibernate04-02为Hibernate05-02,去掉用不到的Node类相关的代码。

2.修改StudentTest.java文件为:

package com.test.service;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.junit.After;import org.junit.Before;import org.junit.Test;import com.test.model.Class;import com.test.model.Student;import com.test.util.HibernateUtil;public class StudentTest {private SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); // 获取Session工厂private Session session;@Beforepublic void setUp() throws Exception {session=sessionFactory.openSession(); // 生成一个session    session.beginTransaction(); // 开启事务}@Afterpublic void tearDown() throws Exception {session.getTransaction().commit(); // 提交事务    session.close(); // 关闭session}@Testpublic void testClassAndStudentSave() {Class c = new Class();    c.setName("08数学");        Student s1 = new Student();    s1.setName("张三");    s1.setC(c);        Student s2 = new Student();    s2.setName("李四");    s2.setC(c);        session.save(s1);    session.save(s2);}}

运行函数testClassAndStudentSave(),hibernate就会把c、s1、s2的数据保存到数据库中。这里虽然没有对c调用session.save方法,但是由于我们在Student类的映射文件中设置了级联保存,所以c的数据也会保存到数据库中。


二、load()方法VS get()方法
都是根据OID(对象标识符,也就是对象的主键) 从数据库中加载一个持久化对象。
区别1:假如数据库中不存在与OID 对应的记录,Load()方法会抛出异常,而get()方法返回null;
区别2:load 方法默认采用延迟加载策略,get 方法采用立即检索策略;

添加测试函数:

@Testpublic void testLoadClass(){Class c = (Class) session.load(Class.class, Long.valueOf(2));System.out.println(c);}

数据库中t_class表中只有一条主键是1的数据,我们这里要获取主键是2的数据。运行这个函数,程序报错:


这里提示对象不存在:给定的标识符不存在。

添加测试函数:

@Testpublic void testGetClass(){Class c = (Class) session.get(Class.class, Long.valueOf(2));System.out.println(c);}

这里使用get方法获取主键是2的Class对象。程序没有报错,程序输出为null



load方法和get方法还有一个重要的区别是:load方法采用延迟加载策略,而get方法是立即加载策略。什么是延迟加载策略呢?当调用load方法的时候获取的是这个对象的一个引用,并没有给对象加载数据,当需要用到的时候才会加载数据。

我们现在函数为:

@Testpublic void testLoadClass(){Class c = (Class) session.load(Class.class, Long.valueOf(1));System.out.println(c.getStudents());}

把断点设置在输出代码一行,运行程序:


发现此时c对象中的数据都是没有值的。运行下一步打印代码:发现数据打印出来了,用到的时候才会去加载数据。


这里当获取一个对象是为了删除这个对象,使用load方法就可以了。当需要访问这个对象的数据时,使用get比较好。

修改get方法测试函数为:

@Testpublic void testGetClass(){Class c = (Class) session.get(Class.class, Long.valueOf(1));System.out.println(c.getStudents());}

同样使用断点调试:发现当调用get方法的时候就会给对象加载数据了


三、update()方法将一个游离对象转变为持久化对象;

@Testpublic void testUpdateClass(){Session session1=sessionFactory.openSession(); // 生成一个session    session1.beginTransaction(); // 开启事务Class c = (Class) session1.get(Class.class, Long.valueOf(1));session1.getTransaction().commit(); // 提交事务    session1.close(); // 关闭session        Session session2=sessionFactory.openSession(); // 生成一个session    session2.beginTransaction(); // 开启事务c.setName("08数学2");session2.update(c);session2.getTransaction().commit(); // 提交事务    session2.close(); // 关闭session}

这个测试函数中,我们首先开启了一个新的session1,使用session1得到持久化对象c,此时关闭session1,c变成了游离对象。新建session2,修改游离对象c的数据,并调用session2的update方法,此时会发现数据库中信息发生了变化,c变成了持久化对象。


四、saveOrUpdate()方法包含了save()和update()方法。这里如果传入的是临时对象就调用save方法,如果调用的是游离对象就调用update方法。

@Testpublic void testSaveOrUpdateClass(){Session session1=sessionFactory.openSession(); // 生成一个session    session1.beginTransaction(); // 开启事务Class c = (Class) session1.get(Class.class, Long.valueOf(1));session1.getTransaction().commit(); // 提交事务    session1.close(); // 关闭session        Session session2=sessionFactory.openSession(); // 生成一个session    session2.beginTransaction(); // 开启事务c.setName("08数学3");session2.saveOrUpdate(c);Class c2 = new Class();c2.setName("09数学3");session2.saveOrUpdate(c2);session2.getTransaction().commit(); // 提交事务    session2.close(); // 关闭session}


五、merge()方法,合并对象。

使用update方法会存在一个问题,看如下的测试方法:

@Testpublic void testUpdateClass2(){Session session1=sessionFactory.openSession(); // 生成一个session    session1.beginTransaction(); // 开启事务Class c = (Class) session1.get(Class.class, Long.valueOf(1));session1.getTransaction().commit(); // 提交事务    session1.close(); // 关闭session        Session session2=sessionFactory.openSession(); // 生成一个session    session2.beginTransaction(); // 开启事务    Class c2 = (Class) session2.get(Class.class, Long.valueOf(1));c.setName("08数学2");session2.update(c);session2.getTransaction().commit(); // 提交事务    session2.close(); // 关闭session}

这里调用update方法之前c为游离对象,c2为持久化对象,这时c存在于内存中,c2存在于session缓存中。运行方法,报错为:


这里提示非唯一的对象:一个具有相同标识符的对象已经存在于session缓存中。

这里调用update方法把c变成持久化对象时,发现session缓存中已经存在了一个与c具有相同标识符的对象,从而报错。

但是调用merge方法的话,会先把这两个对象的属性合并,然后再更新:

@Testpublic void testMergeClass(){Session session1=sessionFactory.openSession(); // 生成一个session    session1.beginTransaction(); // 开启事务Class c = (Class) session1.get(Class.class, Long.valueOf(1));session1.getTransaction().commit(); // 提交事务    session1.close(); // 关闭session        Session session2=sessionFactory.openSession(); // 生成一个session    session2.beginTransaction(); // 开启事务    Class c2 = (Class) session2.get(Class.class, Long.valueOf(1));c.setName("08数学4");session2.merge(c);session2.getTransaction().commit(); // 提交事务    session2.close(); // 关闭session}

运行程序,发现数据库中数据更新成功。


六、delete()方法,删除对象。这个比较简单了,用于从数据库表中删除对象。

@Testpublic void testDeleteClass(){Student student = (Student)session.load(Student.class, Long.valueOf(1));session.delete(student);}

这里必须提交事务后,才会刷新缓存,同步数据库。



0 0
原创粉丝点击