Hibernate_一级缓存_延迟加载_持久化
2017-10-31 21:48
225 查看
Hibernate框架是当今主流的Java持久层框架之一它是一个开放源代码的对象关系映射(orm)框架.
1.持久化类:
持久化:就是将内存中的数据永久存储到关系型数据库中;
持久化类:指一个Java类与数据库表建立了映射关系,也就是javaBean和相对应的映射文件就是一个持久化类;
持久化类的特点:
1. 需要提供无参的构造方法,因为要在Hibernate的底层使用反射生成类的实例;
2. 属性要私有,对私有的属性提供公有的get和set方法,因为要在Hibernate底层会将查询到的数据进行封装;
3. 尽量使用包装类的类型,因为包装类和基本数据类型的默认值不同,包装类的默认值为null更符合逻辑;
4. 持久化类要有一个唯一标识OID与表的主键相对应;
5. 持久化类尽量不要使用final进行修饰,因为在延迟加载时会生成一个代理对象,相当于它的子类,如果用final修饰之后延迟加载这个机制就失效了.
JaveBean的编写规范是什么:
1. 类都是public的;
2. 都有默认的无参构造函数;
3. 成员变量都是私有的;
4. 都有公共的set/get方法;
5. 一般都实现Serializable接口.
2.hibernate的主键生成策略:
主键类型:
1. 自然主键:把具有业务含义的字段作为主键,例如在customer表中,如果把name字段作为主键,前提条件必须是每一个客户的name都不允许为null
2. 代理主键:把不具备业务含义的字段作为主键,例如加一个id,与表中其他字段都没有业务关系.
主键生成策略:
1. increment:用于long short 或int 类型,由Hibernate自动以递增的方式生成唯一标识符,每次增量为1,不能在集群环境下使用,适用于代理主键;
2. identity:采用底层数据库本身提供的主键生成标识符,条件是数据库支持自动增长的数据类型,在DB2,MySQL,MSSQL Server,Sybase 和HypersonicSQL数据库中可以使用该生成器,该生成器要求在数据库中把主键定义为自动增长类型,使用于代理主键;
3. sequence:Hibernate根据底层数据库序列生成标识符,条件是数据库支持序列,适用于代理主键.
4. Native:根据底层数据库对自动生成表示符的能力来选择identity,sequence,hilo三种生成器中的一种,适合跨数据库平台开发.适用于代理主键
5. UUID:Hibernate采用128位的UUid算法来生成标识符,其UUID被编码为一个长度为32位的十六进制字符串,适用于代理主键
6. Assigned:由java程序负责生成标识符,如果不指定id元素的generator属性,则默认使用该主键生成策略.,使用于自然主键;
3.Hibernate的一级缓存:
指Session缓存,Session缓存是一块内存空间, 用来存放相互管理的java对象,在使用Hibernate查询对象的时候,首先会使用对象属性的OID值在Hibernate的一级缓存中进行查找,如果找到匹配的OID值,就直接将该对象从一级缓存中取出使用,不会再查询数据库;如果没有找到相同的OID值的对象,则会去数据库中查找相应的数据.当从数据库中查询到所需数据时,该数据信息也会放置到一级缓存中,作用就是减少对数据库的访问次数,降低服务器的压力.
一级缓存的特点:
l 当应用程序调用Session接口的save()、update()、saveOrUpdate时,如果Session缓存中没有相应的对象,Hibernate就会自动的把从数据库中查询到的相应对象信息加入到一级缓存中去。
l 当调用Session接口的load()、get()方法,以及Query接口的list()、iterator()方法时,会判断缓存中是否存在该对象,有则返回,不会查询数据库,如果缓存中没有要查询对象,再去数据库中查询对应对象,并添加到一级缓存中。
l 当调用Session的close()方法时,Session缓存会被清空。
快照机制:
Hibernate向一级缓存放入数据时,同时复制一份数据放入到Hibernate快照中,当使用commit()方法提交事务时,同时会清理Session的一级缓存,这时会使OID判断一级缓存中的对象和快照中的对象是否一致,如果两个对象中的属性发生变化,则执行update语句,将缓存的内容同步到数据库,并更新快照;如果一致,则不执行update语句.Hibernate快照的作用就是确保一级缓存中的数据和数据库中的数据保持一致.
4.Hibernate对象的三种状态:
A)瞬时态(transient)
瞬时态也称为临时态或者自由态,瞬时态的实例是由new命令创建、开辟内存空间的对象,不存在持久化标识OID(相当于主键值),尚未与Hibernate Session关联,在数据库中也没有记录,失去引用后将被JVM回收。瞬时状态的对象在内存中是孤立存在的,与数据库中的数据无任何关联,仅是一个信息携带的载体。
OID没有值,没有和session建立关系
B)持久态(persistent)
持久态的对象存在持久化标识OID,加入到了Session缓存中,并且相关联的Session没有关闭,在数据库中有对应的记录,每条记录只对应唯一的持久化对象,需要注意的是,持久态对象是在事务还未提交前变成持久态的。
OID有值,和session建立关系,进入缓存,拥有了快照
C)脱管态(detached)
脱管态也称离线态或者游离态,当某个持久化状态的实例与Session的关联被关闭时就变成了脱管态。脱管态对象存在持久化标识OID,并且仍然与数据库中的数据存在关联,只是失去了与当前Session的关联,脱管状态对象发生改变时Hibernate不能检测到。
OID依然存在,和session失去关联
学习对象状态我们要明确的:
a、是为了更好的掌握hibernate中操作的方法。b、区分状态只有两个标识
一是否有OID
二是否和Session建立的关系
临时状态:
没有OID,和Session没有关系。
持久化状态:
有OID,和Session有关系。
脱管状态:
有OID,和Session没有关系。
5. 延迟加载:
首先延迟加载是调用的load()方法,即使有对数据库操作的代码,也不会立马去查询数据库,只有用到了查询结果,才会去发送sql语句,操作数据库.
关闭延迟加载:lazy=”false”
立即加载:
调用的是get()方法,不管什么时候执行对数据库的操作,立马会去执行sql,操作数据库
延迟加载和立即加载的区别:
a) 延迟加载提升了性能;
b) 查询时机不一样;
c) 返回值不一样,get()返回的是对象,而load()返回的是代理对象,没有地址值,通过继承的方式生成的代理对象
相关文章推荐
- Hibernate 延迟加载剖析与代理模式应用
- Hibernate: 关于延迟加载(lazy)和强制加载 : Hibernate.initialize()
- hibernate 延迟加载问题探讨
- Hibernate中延迟加载和缓存
- hibernate延迟加载(get和load的区别)
- spring+hibernate引起的延迟加载
- 转 Hibernate延迟加载机制
- Hibernate延迟加载、三种状态、脏检查 缓存
- hibernate的延迟加载及其与session关闭的矛盾
- hibernate 延迟加载和抓取策略
- Hibernate延迟加载与opensessioninviewFilter
- 自己编写的一个Json工具类,实现了反射将整个Object转换为Json对象的功能,支持Hibernate的延迟加载对象
- Hibernate延迟加载-by宋迪
- 再说hibernate延迟加载问题
- HIbernate延迟加载(转)
- hibernate 延迟加载
- Could not initialize proxy - the owning Session was closed ---Hibernate与延迟加载:
- hibernate延迟加载(get和load的区别)
- hibernate延迟加载的使用和部分源码解析
- hibernate复习4 延迟加载2--集合