06.Hibernate实体类生命周期
1.Hibernate的Session缓存
- 减少访问数据库的频率,当Session的get()方法试图从数据库中加载一个对象时,Session先判断缓存中是否存在这个对象,如果存在就不需要再从数据库中检索,而直接从缓存中获取这个对象。
- 当缓存中的持久化对象之间存在循环关系是,Session会保证不会出现访问对象图的死循环,以及由循环引起的JVM堆栈溢出异常。
- Session能保证数据库中的相关记录与缓存中相应的对象保持同步。Session在清理缓存的时候会自动进行脏检查,如果发现Session缓存中的对象与数据库中的相应的记录不一致,就会根据对象的最新属性去同步更新数据库。
- 按照应用程序调用session.save()方法的先后顺序,执行所有对实体类进行插入的insert语句。
- 执行所有对实体类进行更新的update语句。
- 执行所有对实体类集合进行删除的delete语句。
- 执行所有对实体类集合进行删除、更新或者插入的SQL语句。
- 执行所有对实体类集合进行插入的insert语句。
- 按照应用程序调用session.delete()方法的先后顺序,执行所有对实体类进行删除的delete语句。
- 当应用程序调用org.hibernate.Transaction的commit()方法时,commit()方法先清理缓存,再提交事务。
- 当应用程序调用Hibernate执行查询时,如果缓存中的对象与数据库中的不一致(即缓存中的对象已发生变化),Hibernate就会先清理缓存再执行查询,以保证查询得到正确的数据。
- 当应用程序显式调用Session的flush()方法时。
|
清理缓存的模式 |
查询 |
commit()方法 |
flush()方法 |
|
FlushMode.AUTO |
清理 |
清理 |
清理 |
|
FlushMode.COMMIT |
不清理 |
清理 |
清理 |
|
FlushMode.NEVER |
不清理 |
不清理 |
清理 |
2.实体类在Hibernate容器中的状态
- 临时状态(transient):刚用new语句创建,还未被持久化的并且不在Session的缓存中的实体类。
- 持久化状态(persistent):已被持久化,并且在Session缓存中的实体类。
- 删除状态(removed):不在Session缓存中,而且Session已计划将其从数据库中删除的实体类。
- 游离状态(detached):已被持久化,但不再处于Session的缓存中的实体类。
- 在使用代理主键的情况下,OID为null。
- 不在Session缓存中。
- 在数据库中没有对应的记录。
- OID不为null。
- 在Session缓存中
- 数据库中有对应的记录。
- OID不为null。
- 不在Session缓存中。
- Session计划将其从数据库中删除。
- Session在清理缓存时,会执行相应的delete语句。
- OID不为null。
- 不在Session缓存中。
- 数据库中有对应的记录。
3.Session接口的详细用法
- 创建Configuration对象,调用Configuration对象读取配置文件。
- 创建ServiceRegistry对象,注册Hibernate服务。
- 调用Configuration.buildSessionFactory(ServiceRegistry)方法创建SessionFactory对象。
Configuration cfg = new Configuration();cfg.configure();ServiceRegistry sr = new ServiceRegistryBuilder().applySettings(cfg.getProperties()).buildServiceRegistry();SessionFactory sf = cfg.buildSessionFactory(sr);
// 1.读取默认名称的配置文件cfg.configure();// 2.读取指定名称的配置文件cfg.configure("hibernate.cfg.xml");// 3.程序设置配置属性cfg.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQLInnoDBDialect").setProperty("hibernate.connection.datasource", "java:comp/env/jdbc/test").setProperty("hibernate.order_updates", "true");
// 1.读取配置文件cfg.addResource("Student.hbm.xml").addResource("Teacher.hbm.xml");// 2.读取类cfg.addClass(vo.Student.class).addClass(model.Teacher.class);
// 1.推荐的方式ServiceRegistry sr = new ServiceRegistryBuilder().applySettings(cfg.getProperties()).buildServiceRegistry();SessionFactory sf = cfg.buildSessionFactory(sr);// 2.此种方式已过时SessionFactory sessions = cfg.buildSessionFactory();
// 1.要配置"hibernate.current_session_context_class",如果前一个Session未close,从上下文得到Session,不一定会new一个新的。建议使用。Session s=sf.getCurrentSession();// 2.一定会new一个新的SessionSession s=sf.openSession();
- 执行save()方法并不会立即执行insert语句,如果调用save()方法后又修改了实体类的属性,那么在Session清理缓存时会执行额外的update语句。
- 在使用代理主键的场合,无论Java对象处于临时状态、持久化状态、删除状态还是游离状态,应用程序都不应该修改它的OID,因此比较安全的做法是把实体类的setId()方法设置成protected类型。
- save()方法是用来保存临时对象的,在应用程序中不应该把持久化对象或游离对象传给save()方法。
- Session的update()方法可以使一个游离对象转变为持久化对象,并且执行一条update语句,对于同一个实体类即是多次修改了其属性,在清理缓存时也只会执行一条update语句。
- 默认情况下,只要调用了update()方法在清理缓存时就会执行一条update语句,如果希望只有修改了实体类属性值才执行update语句,可以设置<class>元素的属性select-before-update="true",这样在update前会先执行一条select语句,对比要更新的实体类属性是否被修改了,只有在修改了实体类属性的情况下才会执行update语句。
- saveOrUpdate()方法同时包含了update()与save()的功能,如果传入的是临时对象就调用save(),如果传入的是游离对象就调用update(),如果传入的是持久化对象就直接返回。
- OID为null。
- 实体类有version版本控制属性并取值为null。
- 在映射文件为<id>元素设置了unsaved-value属性,并且OID值与其匹配。
- 在映射文件中为version版本控制属性设置了unsaved-value属性,并且实体类的version值与其匹配。
- 为Hibernate的Interceptor(拦截器)提供了自定义的实现,并且Interceptor实现的isUnsaved()方法返回true。
- 如果传入的参数是游离对象,先使游离对象被当前Session关联,使他它变为持久化对象。如果传入的是持久化对象,则忽略这一步。之所以让游离对象变成持久化对象,是为了在使用Interceptor(拦截器)时,Interceptor能正常工作。
- 计划执行一个delete语句。
- 把对象从Session缓存中删除,该对象进入删除状态。
Session session1 = sessionFactory1.openSession();Teacher teacher =(Teacher) session1.get(Teacher.class, new Long(1));session1.close();Session session2 = sessionFactory2.openSession();Transaction transaction = session2.beginTransaction();session2.replicate(teacher, ReplicationMode.LATEST_VERSION);transaction.commit();session2.close();
4.Hibernate级联操作实体类
- "none":当Session操纵当前对象时,忽略其他关联的对象,这是默认值。
- "save-update":当调用save()、update()、saveOrUpdate()时,级联保存临时对象,级联更新游离对象。
- "persist":当调用persist()保存对象时,级联保存临时对象。
- "merge":当调用merge()方法时,会级联融合所有关联的游离对象。
- "delete":当调用delete()方法时,会级联删除关联的对象。
- "lock":当调用Session的lock()方法时,会把关联的游离对象加到Session缓存中。
- "replicate":当调用replicate()方法时,会级联复制所有关联的对象。
- "evict":当调用evict()方法时,会清除所有关联的对象。
- "refresh":当调用refresh()方法时,会刷新所有关联的对象。
- "all":包含save-update、persist、merge、delete、lock、replicate、evict、refresh的级联操作行为。
- "delete-orphan":删除所有和当前对象解除关联关系的对象。
- "all-delete-orphan":包含all和delete-orphan的行为。
06.Hibernate实体类生命周期的更多相关文章
- Hibernate学习(4)- Hibernate对象的生命周期
1.Hibernate对象的生命周期(瞬时状态.持久化状态.游离状态) 1.瞬时状态(Transient): 使用new操作符初始化的对象就是瞬时状态,没有跟任何数据库数据相关联:2.持久化状态(Pa ...
- spring+hibernate实体类注解详解(非原创) + cascade属性取值
@Entity //继承策略.另一个类继承本类,那么本类里的属性应用到另一个类中 @Inheritance(strategy = InheritanceType.JOINED ) @Table(nam ...
- eclipse从数据库逆向生成Hibernate实体类
做项目必然要先进行数据库表设计,然后根据数据库设计建立实体类(VO),这是理所当然的,但是到公司里做项目后,让我认识到,没有说既进行完数据库设计后还要再“自己”建立一变VO.意思是,在项目设计时,要么 ...
- [转]eclipse借助hibernate tool从数据库逆向生成Hibernate实体类
如何从数据库逆向生成Hibernate实体类呢??? 1. 首先,要在eclipse中采用自带的数据库管理器(Data Management),连通你的数据库: 然后选择数据库,这里用的oracle, ...
- Intellij idea生成Hibernate实体类
反向生成基于注解的Hibernate实体类 1. 为项目添加Hibernate支持 2. 在IDE右边找到database,然后按照步骤添加数据. 3. 保存后.在主面板左侧有persistence, ...
- (转)JVM类生命周期概述:加载时机与加载过程
原文地址: http://blog.csdn.net/justloveyou_/article/details/72466105 JVM类加载机制主要包括两个问题:类加载的时机与步骤 和 类加载的方式 ...
- Eclipse从数据库逆向生成Hibernate实体类和映射文件(Eclipse插件系列之HibernateTools)
♣下载安装Eclipse插件(HibernateTools) ♣Eclipse连接数据库(Mysql5.7) ♣新建hibernate.properties和hibernate.cfg.xml文件 ♣ ...
- (转) Eclipse通过HibernateTools实现逆向生成Hibernate实体类
背景:工作中使用Hibernate进行持久化的开发工作,所以有必要详细了解这方面的知识. ps:这里有个问题就是刷新表的时候速度太慢了.还不如自己手动去创建.如果表太多倒是可以采取批量生成的策略. 在 ...
- JVM类生命周期概述:加载时机与加载过程
一个.java文件在编译后会形成相应的一个或多个Class文件,这些Class文件中描述了类的各种信息,并且它们最终都需要被加载到虚拟机中才能被运行和使用.事实上,虚拟机把描述类的数据从Class文件 ...
随机推荐
- HTML中Meta标签大全
在网页的HTML源代码中一个重要的代码“”(即通常所说的META标签).META标签用来描述一个HTML网页文档的属性,例如作者.日期和时间.网页描述.关键词.页面刷新等. 1.META标签的keyw ...
- VS2010 自动关闭的问题解决方法
分为如下几个解决方法: 没有安装VS2010的SP1,安装后,问题解决了 自定义设置,出现了不正确的情况,执行 devenv.exe /resetsettings 可以排除故障 使用 devenv.e ...
- Lucene全文检索框架
1.什么时Lucene? 是一个全文搜索框架,而不是应用产品,他只是一种工具让你能实现某些产品,并不像www.baidu.com拿来就能用 是apache组织的一个用java实现的全文搜索引擎的开源项 ...
- js动态显示可输入字数并提示还可以输入的字数
动态显示可输入的字数提示还可以输入的字数. 代码: <input name="title" type="text" size="50" ...
- C#创建、读取和修改Excel
// Namespaces, Variables, and Constants using System; using System.Configuration; using System.Data; ...
- USB总线介绍
•USB 1.0出现在1996年的,速度只有1.5Mb/s1998年升级为USB 1.1,速度也提升到12Mb/s,称之为”full speed” •USB2.0规范是由USB1.1规范演变而来的.它 ...
- psql: 致命错误: 用户 "postgres" Ident 认证失败
RedHat: 问题: psql -U postgres 时出现:psql: 致命错误: 用户 "postgres" Ident 认证失败 解决: 修改 /var/lib/pgs ...
- ListView用法及加载数据时的闪烁问题和加载数据过慢问题
ListView介绍及添加数据时的闪烁问题 1. ListView类 1.1 ListView常用的基本属性: (1)FullRowSelect:设置是否行选择模式.(默认为false) 提示 ...
- Unix 编程
1. Users and Groups 真实用户ID和真实组ID 真实用户ID和组ID表示运行进程的真实用户 ID 和 组ID. 有效用户ID和有效组IDp 有效 ID 是进程进行相关操作(比如系统调 ...
- linux 下的使用 ln 创建 软链接 和 硬链接
linux 下的一个指令 ln 作用: 创建软链接或者硬链接 Linux 系统下每创建一个文件,系统都会为此文件生成一个 index node 简称(inode) ,而每一个文件都包含用户数据(use ...