1、对象状态

1.1   状态介绍

hibernate 规定三种状态:瞬时态、持久态、脱管态

瞬时态:transient,session没有缓存对象,数据库也没有对应记录。没有与hibernate关联,与数据库中的记录没有产生关联。

OID特点:没有值

持久态:persistent,session缓存对象,数据库最终会有记录。(事务没有提交)与hibernate关联,对象有id

OID特点:有值

脱管态:detached,session没有缓存对象,数据库有记录。没有与hibernate关联,对象有id

OID特点:有值

1.2 对象转换

1.2.1 瞬时态/临时态

1  获得:一般都只直接创建(new)

2  瞬时态 转换 持久态

一般操作:save方法、saveOrUpdate

3 瞬时态 转换 脱管态

一般操作:通过setId方法设置数据

例如:

User user = new User();        //瞬时态

user.setUid(1);                            //脱管态

1.2.2 持久态

1 获得:

查询操作:get、loat、createQuery、createCriteria 等 获得都是持久态【】

执行save之后持久态

执行update之后持久态

2  持久态 转换 瞬时态

官方规定执行delete()  --民间:删除态

3  持久态 转换 脱管态

session没有记录

session.close () 关闭

session.clear() 清除所有

session.evict(obj) 清除指定的PO对象

1.2.3   脱管态/游离态

1  获得:

创建、并设置OID的

通过api获得

2 脱管态 转换 瞬时态

手动去除OID,设置成默认值

3  脱管态 转换 持久态

一般操作:update()、saveOrUpdate

总结:

持久状态,我们使用Hibernate主要是为了持久化我们的数据.
 对于对象的状态,我们期望我们需要同步到数据库的数据,都被装换成持久状态
/持久化状态特点: Hibernate会自动将持久化状态对象的变化同步到数据库中

代码实现:

package com.alice.hibernate02.a_statue;

import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test; import com.alice.hibernate02.util.HibernateUtil;
import com.alice.hibernate02.vo.User; public class Status01Test {
@Test
//演示三种状态
public void statue01Test(){
Session session = HibernateUtil.openSession(); Transaction tran = session.beginTransaction(); User user = new User();// 瞬时状态
user.setName("lili");// 瞬时状态
user.setPassword("12233");// 瞬时状态 session.save(user);// 持久状态调用完save方法,数据库中有没有对应记录?
// 没有对应记录, 但是最终会被同步到数据库中.仍然是持久状态. tran.commit();//持久状态 session.close();//游离状态 }
@Test
public void statue02Test(){
Session session = HibernateUtil.openSession(); Transaction tran = session.beginTransaction(); User user = new User();// 瞬时状态
user.setName("lili");// 瞬时状态
user.setPassword("12233");// 瞬时状态 session.save(user);//save方法会使用主键生成策略,为User指定id.
//主键自增 => 打印 insert语句
// increment=> select max(id) ....
//assigned => 需要手动指定主键,不指定将会报错 tran.commit();
session.close();
}
@Test
// 瞬时=> 游离
// 瞬时: 没有关联,没有id
// 游离: 没有关联,有id(与数据库中对应的id)
public void statue03Test(){
Session session = HibernateUtil.openSession(); Transaction tran = session.beginTransaction(); //............
User user = new User();//瞬时态 user.setId(1);//游离态 //----------------------------------------------------
session.getTransaction().commit(); // 持久状态
//事务提交时,会把持久化状态对象同步到数据库中
session.close(); // 游离状态
}
// @Test
// 持久=> 瞬时
// 持久: 有关联,有id
// 瞬时: 无关联,无id
// public void statue04Test(){
// Session session = HibernateUtil.openSession();
//
// Transaction tran = session.beginTransaction();
//
// //............
// //通过get方法,得到持久状态对象
// User user = (User) session.get(User.class, 1);
//
//
// //----------------------------------------------------
// session.getTransaction().commit(); // 持久状态
// //事务提交时,会把持久化状态对象同步到数据库中
// session.close(); // 游离状态
//
// user.setId(null);//瞬时态
// }
@Test
// 持久=> 游离
// 只需要将session的关联取消
public void statue05Test(){
Session session = HibernateUtil.openSession(); Transaction tran = session.beginTransaction(); //............
User user = new User();//瞬时态 session.evict(user);//游离 //----------------------------------------------------
session.getTransaction().commit(); // 持久状态
//事务提交时,会把持久化状态对象同步到数据库中
session.close(); // 游离状态
}
@Test
// 游离=> 瞬时
// 移除ID
public void statue06Test(){
Session session = HibernateUtil.openSession(); Transaction tran = session.beginTransaction(); //............
User user = new User();//瞬时态 session.evict(user);//游离 user.setId(null);//瞬时
//----------------------------------------------------
session.getTransaction().commit(); // 持久状态
//事务提交时,会把持久化状态对象同步到数据库中
session.close(); // 游离状态
}
@Test
// 游离=> 持久
// 是否与Session关联
public void fun8(){
Session session = HibernateUtil.openSession();
session.beginTransaction();
//------------------------------------------------
//通过get方法,得到持久状态对象
User u= (User) session.get(User.class, 1); // 持久状态 session.evict(u);//游离 session.update(u);//持久
//----------------------------------------------------
session.getTransaction().commit(); // 持久状态 -> 打印update语句
session.close(); // 瞬时状态
} }

2、  一级缓存

2.1 介绍session缓存

一级缓存:又称为session级别的缓存。当获得一次会话(session),hibernate在session中创建多个集合(map),用于存放操作数据(PO对象),为程序优化服务,如果之后需要相应的数据,hibernate优先从session缓存中获取,如果有就使用;如果没有再查询数据库。当session关闭时,一级缓存销毁。

//证明session缓存的存在
public void statue01Test(){
Session session = HibernateUtil.openSession(); Transaction tran = session.beginTransaction(); User user1 = (User) session.get(User.class, 1);// 发送select语句,从数据库取出记录.并封装成对象
// 持久化状态对象=> 存到缓存中
System.out.println("user1"+user1); User user2 = (User) session.get(User.class, 1);//再次查询时,会从缓存中查找,不会发送select
System.out.println("user2"+user2); System.out.println(user1 == user2); tran.commit();//持久状态 session.close();//游离状态 }

2.2   一级缓存快照

l  快照:与一级缓存一样的存放位置,对一级缓存数据备份。保证数据库的数据与 一级缓存的数据必须一致。如果一级缓存修改了,在执行commit提交时,将自动刷新一级缓存,执行update语句,将一级缓存的数据更新到数据库。

@Test
//session缓存中的快照
public void cache02Test(){
Session session = HibernateUtil.openSession(); Transaction tran = session.beginTransaction(); User user1 = (User) session.get(User.class, 1);// 发送select语句,从数据库取出记录.并封装成对象 session.update(user1); tran.commit();//持久状态 session.close();//游离状态 }
@Test
//session缓存中的快照
public void cache03Test(){
Session session = HibernateUtil.openSession(); Transaction tran = session.beginTransaction(); User user1 = new User(); user1.setId(1);
user1.setName("aaaa");
user1.setPassword("1435"); session.update(user1); tran.commit();//持久状态 session.close();//游离状态 }

  

// 持久化状态: 本质就是存在缓存中的对象,就是持久化状态.

2.3 缓冲区

package com.alice.hibernate02.a_statue;

import java.util.List;

import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test; import com.alice.hibernate02.util.HibernateUtil;
import com.alice.hibernate02.vo.User; //session缓存 的细节问题
public class DetailsTest {
@Test
// 1.保存对象时使用 save方法
// 保存对象时使用 persist方法
// 区别? 没有区别
// persist(持久) 方法 来自于JPA 接口
// save(保存) 方法来自于Hibernate
public void details01Test() {
Session session = HibernateUtil.openSession(); Transaction tran = session.beginTransaction(); User user = new User();// 瞬时状态
user.setName("lili");// 瞬时状态
user.setPassword("12233");// 瞬时状态 // session.save(user);// insert 语句被打印,读取id
session.persist(user);
tran.commit();// 持久状态 session.close();// 游离状态 } // HQL查询一般不会使用缓存
@Test
public void details02Test() {
Session session = HibernateUtil.openSession(); Transaction tran = session.beginTransaction(); List<User> list1 = session.createQuery("from User").list(); List<User> list2 = session.createQuery("from User").list(); List<User> list3 = session.createQuery("from User").list(); tran.commit();// 持久状态
session.close();// 游离状态 } @Test
// HQL语句批量查询时,查询结果会存入缓冲区
public void details03Test() {
Session session = HibernateUtil.openSession(); Transaction tran = session.beginTransaction(); List<User> list1 = session.createQuery("from User").list(); User user = (User) session.get(User.class, 1); tran.commit();// 持久状态
session.close();// 游离状态 } @Test
// SQL查询,如果把查询结果封装到对象中,对象会放入一级缓存
public void details04Test() {
Session session = HibernateUtil.openSession(); Transaction tran = session.beginTransaction(); List<User> list1 = session.createSQLQuery("select * from t_ser")
.addEntity(User.class).list();
User u = (User) session.get(User.class, 1); System.out.println(u); tran.commit();// 持久状态
session.close();// 游离状态 } @Test
// SQL查询,没有把查询结果封装到对象中,对象不会放入一级缓存
public void details05Test() {
Session session = HibernateUtil.openSession(); Transaction tran = session.beginTransaction(); List<User> list1 = session.createSQLQuery("select * from t_ser").list();
User u = (User) session.get(User.class, 1); System.out.println(u); tran.commit();// 持久状态
session.close();// 游离状态 }
//criteria => 会将查询结果放入一级缓存. 但是查询不会使用一级缓存. 与Hql查询结论一致.
}

//问题: 缓存中的数据如果与数据库中的不同步,会怎么样?
// 会优先使用缓存中的. 使用JDBC
// 在一级缓存中出现该问题的几率比较小.
//openSession==> 一级缓存生命周期开始
//session.close();=> 一级缓存销毁

2.4 其他api

package com.alice.hibernate02.api;

import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test; import com.alice.hibernate02.util.HibernateUtil;
import com.alice.hibernate02.vo.User; //其他API (大部分都是了解)
public class SessionTest {
@Test
// 1. evict 将缓存中的对象移除.
// 2. clear 清空1级缓存
public void session01Test() {
Session session = HibernateUtil.openSession(); Transaction tran = session.beginTransaction(); User user = (User) session.get(User.class, 21);
session.clear(); session.getTransaction().commit();
session.close();// 游离状态 } @Test
// 3 refresh 刷新 => 强制刷新缓存中的对象 => (可以用来解决缓存与数据库数据不同步的问题)
public void session02Test() {
Session session = HibernateUtil.openSession(); Transaction tran = session.beginTransaction(); User user = (User) session.get(User.class, 9);
session.refresh(user);// 将缓存中的对象立刻与数据库同步,会再发送一个sql语句 session.getTransaction().commit();
session.close();// 游离状态 } @Test
// 4 flush 对比快照,并提交缓存对象
public void session03Test() {
Session session = HibernateUtil.openSession(); Transaction tran = session.beginTransaction(); User user = (User) session.get(User.class, 9);
session.flush();// 将缓存中的对象立刻与数据库同步,会再发送一个sql语句 session.getTransaction().commit();
session.close();// 游离状态 } @Test
// 代理主键=> native
// 5.1 aveOrUpdate方法
// saveOrUpdate 可以同时完成保存或更新操作
// 主键为空=>save
// 主键有值=> update
// 自然主键=> assigned
// 5 update 与 saveOrUpdate方法
// saveOrUpdate 可以同时完成保存或更新操作
// 主键为空=> 报错,因为无论是save还是update 都必须指定id
// 主键有值=> 先会根据主键查询数据库.
// 数据库中存在=> 执行update
// 数据库中不存在=> 执行insert
public void session04Test() {
Session session = HibernateUtil.openSession(); Transaction tran = session.beginTransaction(); User user = new User();
user.setId(1);
user.setName("lilaa");
user.setPassword("143325");
session.saveOrUpdate(user); session.getTransaction().commit();
session.close();// 游离状态 }
//在我们使用Hibernate时候,注意要避免出现,两个相同的ID对象.放入一级缓存的情况.
@Test
public void session05Test() {
Session session = HibernateUtil.openSession(); Transaction tran = session.beginTransaction(); User user = (User) session.get(User.class, 1);// 持久化,缓存中存在
session.evict(user); // 游离态,缓存中不存在 User user1 = (User) session.get(User.class, 1);// 持久化,缓存中存在 session.update(user);// 将user重新变为持久化状态,缓存中存在 session.getTransaction().commit();
session.close();// 游离状态 }
}

hibernate学习(5)——对象状态与一级缓存的更多相关文章

  1. Hibernate(四)之对象状态及一级缓存

    一.Hibernate中的对象状态 1.1.瞬时态(临时态) 没有与Hibernate产生关联 与数据库中的记录没有产生关联(有关联就是与数据库中表的id相对应) 获得:一般都只直接创建(new) 瞬 ...

  2. Hibernate框架学习(三)——实体规则、对象状态、一级缓存

    一.Hibernate中的实体规则 1.实体类创建的注意事项 1)持久化类提供无参数构造,因为在Hibernate的底层需要使用反射生成类的实例. 2)成员变量私有,提供公有的get和set方法,需提 ...

  3. hibernate框架学习第三天:对象状态、一级缓存、快照等

    对象的状态 瞬时状态: 瞬时对象(TO) 应用程序创建出来的对象,不受H3控制 注意:TO对象不具有OID,一旦为TO赋值OID,那么此时就不是TO 持久化状态:持久化对象(PO) 受H3控制的对象, ...

  4. Hibernate第七篇【对象状态、一级缓存】

    前言 本博文主要讲解Hibernate的细节-->对象的状态和一级缓存- 对象状态 Hibernate中对象的状态: - 临时/瞬时状态 - 持久化状态 - 游离状态 学习Hibernate的对 ...

  5. 【Hibernate】持久化对象状态及以及缓存

    一.持久化类状态 1.1 三种持久化对象的状态 1.2 区分三种状态 1.3 三种状态对象转换 1.瞬时态 2.持久态 3.脱管态 4.持久态对象有自动更新数据库的能力 一.持久化类状态 1.1 三种 ...

  6. hibernate框架学习之对象状态

    lHibernate对象共有三种状态 •瞬时状态:瞬时对象 •持久化状态:持久化对象 •托管状态:托管对象 l瞬时对象(Transient Object),简称TO l瞬时对象指的是应用程序创建出来的 ...

  7. Hibernate[延迟加载] [三种状态] [脏检查] [缓存机制]

    一.持久化对象的唯一标识 java中按内存地址不同区分同一个类的不同对象,关系数据库用主键区分同一条记录,Hibernate使用OID来建立内存中的对象和数据库中记录的对应关系 什么是OID? 解析: ...

  8. hibernate学习系列-----(3)Session 缓存和持久化生命周期以及Session 基本操作

    Session缓存原理 为了能够在控制台更好的看到我们的hibernate干了些什么,可以在hibernate.cfg.xml文件中写入如下配置: <!-- print all generate ...

  9. myBatis学习(9):一级缓存和二级缓存

    正如大多数持久层框架一样,MyBatis同样提供了一级缓存和二级缓存的支持 1. MyBatis一级缓存基于PerpetualCache的HashMap本地缓存,其存储作用域为 Session,默认情 ...

随机推荐

  1. 快速搭建Webservice接口测试环境

    一.必备工具: apache-tomcat.Axis2(WebService引擎).实例类 二.部署步骤: 1.到apache官网 http://apache.org/ 下载apache-tomcat ...

  2. Python基础11- 函数之自定义函数

    自定义函数语法结构:def fun1([x],[y],....): 语句1 语句2 使用def语句来定义函数,在def后依次写出函数名.小括号.参数(可无).冒号,然后缩进写函数体 1.无参函数:de ...

  3. javascript选取文档元素

    用指定的id属性 用指定的name属性 用指定的标签名字 用指定的CSS类 匹配指定的CSS选择器 通过ID选取元素 var section1 = document.getElementById(&q ...

  4. BZOJ3072 : [Pa2012]Two Cakes

    考虑DP,设$f[i][j]$表示考虑了$a[1..i]$和$b[1..j]$的最小代价. 若$a[i]==b[j]$,则$f[i][j]=\min(f[i-1][j],f[i][j-1])+1$. ...

  5. BZOJ3084 : [Algorithmic Engagements 2011]The Shortest Period

    枚举答案长度$L$,设$A$和$B$分别为第一个循环节和反串的第一个循环节. 1.坏点不在$A$,那么可以暴力匹配检验. 2.坏点不在$B$,那么把串翻转后不在$A$中,转化为1. 3.坏点在$A$和 ...

  6. BZOJ1858[Scoi2010]序列操作 题解

    题目大意: 有一个01序列,现在对于这个序列有五种变换操作和询问操作: 0 a b 把[a, b]区间内的所有数全变成0:1 a b 把[a, b]区间内的所有数全变成1:2 a b 把[a,b]区间 ...

  7. topcoder SRM 623 DIV2 CatchTheBeatEasy

    比较简单的一题,纠结比较久的是把my_cmp和my_minus放在类中,利用sort函数会出现 no matching function for call to ""sort(st ...

  8. 【BZOJ】2237: [NCPC2009]Flight Planning

    题意 \(n(1 \le n \le 2500)\)个点的树,求删掉一条边再加上一条边使得还是一棵树,且任意两点最大距离最小. 分析 考虑枚举删掉每一条边,我们只需要考虑如何加边容易求得新树的最大距离 ...

  9. iOS 开发小结

    一,经历 1> 在编写以前有过的类似的新功能时,如果以前的开发人员没有写明明确的注释和开发需求,一定要仔细阅读所有代码,每一句代码都有它存在的意义. 2> 例如,只以为是[self.ful ...

  10. 高性能分布式内存队列系统beanstalkd(转)

    beanstalkd一个高性能.轻量级的分布式内存队列系统,最初设计的目的是想通过后台异步执行耗时的任务来降低高容量Web应用系统的页面访问延迟,支持过有9.5 million用户的Facebook ...