Java Hibernate 之 Session 状态
Session接口是Hibernate向程序提供操纵数据库的最主要接口,是单线程对象,它提供了基本的保存、更新、删除和查询方法。它有一个缓存,保存了持久化对象,当清理缓存时,按照这些持久化对象同步更新数据库。
注意:session的某些方法(persist,load)不会立即把改动写入数据库,而是缓存到session的一级缓存中,除非显示调用flush,或者关闭session时才会更新到数据库
- 临时状态(Transient):没与session关联
- 持久化状态(Persistent):与session关联,没close
- 游离状态(Detached):当session.close后
Session的方法详解
1.保存
save:立即插入数据库,并且返回主键
persist:不立即(延迟)插入数据库,无返回值
2.获取
load:加载对象后,对对象的改动不会立即刷新到db,必须flush到db
ex: User user=session.load(User.class,2);
user.setName(‘gt’);
user.flush(); (延迟加载)
get:加载对象后,对对象的改动立即刷新到db
3.更新
update:持久化对象,更新
saveOrUpdate:包含save()和update()功能,如果传入的参数是临时对象(没有保存过)就调用save()方法;如果传入的参数是游离对象,就调用update()方法
merge:不会持久化对象,只会把托管对象的修改更新到db
4.删除
delete:从数据库中删除与JAVA对象对应的记录
5.清理
flush:把缓存同步到db
clear:清除session的缓存大小(更新批量时,应考虑)
三种状态的转换关系
下面通过实例讲解:
实体:
- package cn.itcast.h_session_method;
- public class User {
- private Integer id;
- private String name;
- private byte[] data = new byte[1024 * 1024 * 5];
- public Integer getId() {
- return id;
- }
- public void setId(Integer id) {
- this.id = id;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- }
映射文件:
- <?xml version="1.0"?>
- <!DOCTYPE hibernate-mapping PUBLIC
- "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
- "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
- <hibernate-mapping package="cn.itcast.h_session_method">
- <!--
- lazy属性:默认为true,默认可以懒加载。
- -->
- <class name="User" table="user" lazy="true">
- <id name="id">
- <generator class="native"></generator>
- </id>
- <property name="name"/>
- </class>
- </hibernate-mapping>
配置文件:hibernate.cfg.xml
- <?xml version='1.0' encoding='utf-8'?>
- <!DOCTYPE hibernate-configuration PUBLIC
- "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
- "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
- <hibernate-configuration>
- <session-factory>
- <!--数据库连接设置 -->
- <property name="connection.driver_class">
- com.mysql.jdbc.Driver
- </property>
- <property name="connection.url">
- jdbc:mysql://localhost:3306/mytest
- </property>
- <property name="connection.username">root</property>
- <property name="connection.password">root</property>
- <!-- 方言 -->
- <property name="dialect">
- org.hibernate.dialect.MySQL5Dialect
- </property>
- <!-- 控制台显示SQL -->
- <property name="show_sql">true</property>
- <!-- 自动更新表结构 -->
- <property name="hbm2ddl.auto">update</property>
- <mapping resource="cn/itcast/h_session_method/User.hbm.xml" />
- </session-factory>
- </hibernate-configuration>
测试文件
- package cn.itcast.h_session_method;
- import org.hibernate.Session;
- import org.hibernate.SessionFactory;
- import org.hibernate.cfg.Configuration;
- import org.junit.Test;
- import com.java1234.util.HibernateSessionFactory;
- public class App {
- private static SessionFactory sessionFactory = HibernateSessionFactory.getSessionFactory();
- // save():把临时状态变为持久化状态(交给Sessioin管理)
- // 会生成:insert into ...
- @Test
- public void testSave() throws Exception {
- Session session = sessionFactory.openSession();
- session.beginTransaction();
- // --------------------------------------------
- User user = new User(); // 临时状态
- user.setName("test");
- session.save(user); // 变为了持久化状态
- // --------------------------------------------
- session.getTransaction().commit();
- session.close();
- user.setName("李四"); // 游离状态
- System.out.println(user.getName()); // 游离状态
- }
- // update():把游离状态变为持久化状态
- // 会生成:update ...
- // 在更新时,对象不存在就报错
- @Test
- public void testUpdate() throws Exception {
- Session session = sessionFactory.openSession();
- session.beginTransaction();
- // --------------------------------------------
- User user = (User) session.get(User.class, 1);
- System.out.println(user.getName()); // 持久化状态
- // session.clear(); // 清除Session中所有的对象
- session.evict(user); // 清除Session中一个指定的对象
- user.setName("newname3");
- session.update(user);
- System.out.println("----");
- // session.flush(); // 刷出到数据库
- // --------------------------------------------
- session.getTransaction().commit(); //
- session.close();
- }
- // saveOrUpdate():把临时或游离状态转为持久化状态
- // 会生成:insert into 或 update ...
- // 在更新时,对象不存在就报错
- // 本方法是根据id判断对象是什么状态的:如果id为原始值(对象的是null,原始类型数字是0)就是临时状态,如果不是原始值就是游离状态。
- @Test
- public void testSaveOrUpdate() throws Exception {
- Session session = sessionFactory.openSession();
- session.beginTransaction();
- // --------------------------------------------
- User user = new User();
- user.setId(3); // 自己生成一个游离状态对象
- user.setName("newName");
- session.saveOrUpdate(user);
- // --------------------------------------------
- session.getTransaction().commit();
- session.close();
- }
- // delete():把持久化或游离转为删除状态
- // 会生成:delete ...
- // 如果删除的对象不存在,就会抛异常
- @Test
- public void testDelete() throws Exception {
- Session session = sessionFactory.openSession();
- session.beginTransaction();
- // --------------------------------------------
- // User user = (User) session.get(User.class, 2); // 持久化
- User user = new User();
- user.setId(300);
- session.delete(user);
- session.flush();
- System.out.println("---");
- // --------------------------------------------
- session.getTransaction().commit();
- session.close();
- }
- // get():获取数据,是持久化状态
- // 会生成:select ... where id=?
- // 会马上执行sql语句
- // 如果数据不存在,就返回null
- @Test
- public void testGet() throws Exception {
- Session session = sessionFactory.openSession();
- session.beginTransaction();
- // --------------------------------------------
- User user = (User) session.get(User.class, 5); // 持久化
- System.out.println(user.getClass());
- // System.out.println("---");
- // System.out.println(user.getName());
- // --------------------------------------------
- session.getTransaction().commit();
- session.close();
- }
- // load():获取数据,是持久化状态
- // 会生成:select ... where id=?
- // load()后返回的是一个代理对象,要求类不能是final的,否则不能生成子类代理,就不能使用懒加载功能了。
- // 让懒加载失效的方式:一、把实体写成final的;二、在hbm.xml中写<class ... lazy="false">
- // 不会马上执行sql语句,而是在第1次使用非id或class属性时执行sql。
- // 如果数据不存在,就抛异常:ObjectNotFoundException
- @Test
- public void testLoad() throws Exception {
- Session session = sessionFactory.openSession();
- session.beginTransaction();
- // --------------------------------------------
- User user = (User) session.load(User.class, 5);
- System.out.println(user.getClass());
- System.out.println("---");
- System.out.println(user.getId());
- System.out.println(user.getName());
- // System.out.println(user.getName());
- // --------------------------------------------
- session.getTransaction().commit();
- session.close();
- }
- // 操作大量数据,要防止Session中对象过多而内存溢出
- @Test
- public void testBatchSave() throws Exception {
- Session session = sessionFactory.openSession();
- session.beginTransaction();
- // --------------------------------------------
- for (int i = 0; i < 30; i++) {
- User user = new User();
- user.setName("测试");
- session.save(user);
- if (i % 10 == 0) {
- session.flush(); // 先刷出
- session.clear(); // 再清空
- }
- }
- // --------------------------------------------
- session.getTransaction().commit();
- session.close();
- }
- @Test
- public void test2() throws Exception {
- Session session = sessionFactory.openSession();
- session.beginTransaction();
- // --------------------------------------------
- User user = (User) session.get(User.class, 5); // 持久化
- System.out.println(user.getName());
- // session.clear();
- // user = (User) session.get(User.class, 5); // 持久化
- session.refresh(user); // 刷新Session缓存中对象的状态,即重新select一下
- System.out.println(user.getName());
- // --------------------------------------------
- session.getTransaction().commit();
- session.close();
- }
- }
对于刚创建的一个对象,如果session中和数据库中都不存在该对象,那么该对象就是临时对象(Transient)
临时对象调用save方法,或者游离对象调用update方法可以使该对象变成持久化对象,如果对象是持久化对象时,那么对该对象的任何修改,都会在提交事务时才会与之进行比较,如果不同,则发送一条update语句,否则就不会发送语句
游离对象就是,数据库存在该对象,但是该对象又没有被session所托管
Java Hibernate 之 Session 状态的更多相关文章
- java框架篇---hibernate之session状态
Session接口是Hibernate向程序提供操纵数据库的最主要接口,是单线程对象,它提供了基本的保存.更新.删除和查询方法.它有一个缓存,保存了持久化对象,当清理缓存时,按照这些持久化对象同步更新 ...
- Hibernate,Session方法使得java对象进入持久化状态;持久化对象特征
以下情况java对象进入持久化状态: session.save()方法把临时对象转变为持久化对象. session.load()和session.get()方法得到的对象总是处于持久化状态. sess ...
- Hibernate(3)——实例总结Hibernate对象的状态和ThreadLoacl封闭的session
俗话说,自己写的代码,6个月后也是别人的代码……复习!复习!复习!涉及的知识点总结如下: Hibernate的内部执行过程(CRUD) 对象的状态及其转换图和例子 使用JUnit测试 使用getCur ...
- Hibernate Open Session In View模式【转】
来源:http://www.yybean.com/opensessioninviewfilter-role-and-configuration 一.作用 Spring为我们解决Hibernate的Se ...
- 简单理解Hibernate三种状态的概念及互相转化
本文描述了Hibernate三种状态的概念及互相转化.Java对象的生命周期中有三种状态,而且互相转化.它们分别是临时状态,持久化状态,以及游离状态. AD:WOT2015 互联网运维与开发者大会 热 ...
- hibernate中session
hibernate中的session是一级缓存,可以理解为进程级的缓存.在进程运行期间一直存在. session可以理解为一个可以操作数据库的对象 具体如何操作数据库? session中有方法, 如果 ...
- Hibernate对象的状态和映射
一. Hibernate对象的状态 实体对象的三种状态: 1) 暂态(瞬时态)(Transient)---实体在内存中的自由存在,它与数据库的记录无关. po在DB中无记录(无副本),po和sessi ...
- hibernate 三种状态的转换
一.遇到的神奇的事情 使用jpa操作数据库,当我使用findAll()方法查处一个List的对象后,给对这个list的实体进行了一些操作,并没有调用update 或者 saveOrUpdate方法,更 ...
- 1.1Hibernate持久化类和Hibernate持久化对象状态
一.持久化对象po类 1.po定义 PO,是Persistent Object的缩写,是持久化类.PO是由PO=POJO+hbm映射配置组成. 2.通俗理解 PO类即持久化类,其实就是一个普通的Jav ...
随机推荐
- 斐波那契数列(fabnacci)java实现
斐波那契数列定义:From Wikipedia, the free encyclopedia http://en.wikipedia.org/wiki/Fibonacci_number In math ...
- HTTPS 详解
1) HTTPS是什么 https 是超文本传输安全协议的缩写.HTTPS主要思想是在不安全的网络上创建一种安全的信道,并且可以在使用适当的加密包和服务器证书可被验证且可被信任时候,对窃听和中间人攻击 ...
- CentOS 6.6下PXE+Kickstart无人值守安装操作系统
一.简介 1.1 什么是PXE PXE(Pre-boot Execution Environment,预启动执行环境)是由Intel公司开发的最新技术,工作于Client/Server的网络模式,支持 ...
- AS 自动生成选择器 SelectorChapek
简介 https://github.com/inmite/android-selector-chapek 设计师给我们提供好了各种资源,每个按钮都要写一个selector是不是很麻烦? 这么这个插件就 ...
- ASP.NET实现省市区三级联动(局部刷新)
跟前一篇ASP.NET实现年月日三级联动(局部刷新)一样,没什么技术含量,直接上代码 <asp:ScriptManager ID="ScriptManager1" runat ...
- cos实现文件上传--推荐
1.导包 2.核心类:MultipartRequest MultipartRequest是request的包装类 参数1:request 参数2:保存路径 参数3:上传文件大小,默认为1M 参数4:编 ...
- 你好,C++(13)这道单选题的答案是A、B、C还是D?3.7 枚举类型
3.7 枚举类型 除了之前我们介绍的数值数据和文字数据之外,在现实世界中,常常还会遇到这样一类数据:一道单选题的答案只能是A.B.C.D四个选项中的某一个:红绿灯的颜色只能是红色,绿色和黄色中的某一 ...
- maven管理的项目出现Error configuring application listener of class org.springframework.web.context.ContextL
eclipse里用maven管理的项目,在运行的时候出现 Error configuring application listener of class org.springframework.web ...
- win7 64位 python3.4&opencv3.0配置安装
参考:http://blog.csdn.net/sun7_she/article/details/50051249 一.安装Python 下载Python3.4.2 网址:https://www.py ...
- 涂抹Oracle—Flashback
11.1 基于flashback查询过去的数据 a.基于时间的查询(as of timestamp) 构造表falsh_tbl,删除数据然后查询 SQL>select * from flash ...