-
hibernate 对象的生命周期:
Transient(自由状态) :内存中自由存在,与数据库中的记录无关,未跟session关联。
Persistent(持久化):由Hibernate容器管理,对象变更会固化到数据库,与session关联且session未关闭。
Detached(游离状态):persistent对象当session实例关闭,就变成游离态,不与session关联,当是与数据库表的记录有关联。 要区别手动创建数据库记录和session创建数据库记录的区别。 -
脏数据:数据对象所携带的信息发生了改变之后的状态。
-
脏数据检查:
1. 数据对象监控:检测数据对象的设置方法是否调用。
2. 数据版本对比:框架维持了对象的最近读取版本,数据提交时进行校验判断。(默认实现) -
数据缓存:
1.事务级别缓存(一级):
基于session生命周期。Session内部维护了一个Map数据类型,
此数据类型中保持了所有与当前Session相关联的数据对象,维护了当前Session中的所有相关Po状态。
缓存可以手动干预:
1.Session.evict: 特定对象从内部缓存中清除;
2.Session.clear: 清空内部缓存。2.应用级别缓存(二级):基于SessionFactory,共享所有的session实例。 考虑俩个情况: 1、数据库是否与其他应用共享。(放弃二级缓存或者细化到表被应用独占) 2、应用是否需要部署在集成环境中(考虑是否引入分布式缓存)。 可以被缓存的数据选择意见: 1.数据不会被第三方应用修改。 2.数据的大小在可接受范围内。 3.数据的更新频率低。 4.统一数据可能会被系统频繁的使用。 5.非关键数据 Hibernate没有提供二级缓存的产品化实现,只是提供了一个基于hashtable的简单缓存以供调试,但为第三方缓存组件提供了接入接口。 使用方法:在hibernate中使用二级缓存,首先就要在hibernate.config.xml配置文件中配置使用哪个厂家的缓存产品, 接着需要配置这缓存产品自己的配置文件,最后配置hibernate中的哪些实体对象要纳入二级缓存的管理中。
3.缓存同步策略:决定了数据对象在缓存中的存取规则。
Hibernate提供的4种缓存同步策略:
1. Read-only:只读,适用于不会发生改变的数据。
2.nonstrict-read-write:并发下,数据同步要求不是严格,数据更新操作频率较低。
3.read-write: 严格的读写缓存,基于时间戳判断机制。用于数据同步严格,不支持分布式缓存。
4.transacional:事务型缓存,必须运行在JTA事务环境中。实现了Repeatable read事务隔离机制,适用于关键数据的缓存。4.数据操作过程中的不确定情况:
1.脏读取:一个事务读取了另一个并行事务未提交的数据。
2.不可重读:一个事务再次读取之前曾读过的数据时,发现被另一个已提交的事务修改。
3.虚读:一个事务重新执行一个查询,返回的记录中包含了其他事务提交的产生了新纪录。事务隔离等级:
事务管理: hibernate:默认实现为JDBC Transaction事务管理。
- 基于JTA的事务管理:由JTA容器实现,提供了夸session的事务管理。
5. 锁:
1.悲观锁:利用数据库提供的锁机制实现,才能保证数据访问的排他性。
Hibernate加锁模式:
1.lockmode.none:无锁机制;
2. lockmode.write:写锁机制;
3. lockmode.read:读锁机制;
以上三种是hibernate内部对数据的使用机制,与数据库无关。
4. lockmode.upgrade:利用数据库的for update子句加锁。
5. lockmode. Upgrade_nowait:oracle的特定实现,利用oracled的for update nowait子句实现加锁;
2.乐观锁:利用版本字段控制,操作的时候校验版本。
1.Class描述符添加Optimistic-locks=“Version”
2.添加Version属性描述符。
Optimistic-locks的属性值有:
None: 无乐观锁:
Version:通过版本机制实现乐观锁;(官方推荐)
Dirty:通过检查发生过变动的属性实现乐观锁:
All :通过检查所有属性实现乐观锁。
6.session对象:Hibernate持久化管理器的核心,相当于JDBC connection对JDBC 而言。
7.主键生成策略:使用native,因为底层会根据常用的数据库自动选择合适的策略。特别的可以采用UUID生成策略。
8.大字段的映射:可以采取java.sql.*,类型。对于oracle数据库不适用,因为其有独特的访问对于BLOG,CLOG对象等。
9. 3种继承模式。
1.table per concrete class 表与子类之间的独立一对一关系,子类对应一张数据库表。
Class 属性中的polymorphism=”implicit”隐式多台模式,加载父类的时候,会加载所有的子类记录。缺陷:父类字段必须保持一致。
2.table per subclass 每个子类对应一张子表,并与主类共享主表。
子表只包含扩展的属性,子表和父表通过关系型数据库的外键相关联。
父类的配置文件:加joined-subclass 节点添加子类的映射。
3.tbale per class hierarchy 表与类的一对多关系。
在一张表中维护所有的字段,包括父类与子类的字段。再通过一个标志字段映射到不用的子类中去。
同样是类似table per subclass 配置,不同的是父类需要加上disciminator节点配置标志字段。子类中配置discriminator-value的值决定映射条件。
10.数据关联:4种类型:一对一,一对多,多对一,多对多。
1.一对一:
主键关联:
一张表设定主键生成器,另一张表的主键共享此值,即生成类型为“foreign”,同时one-to-one节点constrained属性设置为‘true’,约束标识。
唯一外键关联:一张表把另外一张表的主键作为外键。 为多对一关联中的特殊一种。
2.一对多:单项一对多,双向一对多。
单向一对多关系只需在“一”方进行配置,双向一对多关系需要在关联双方加以配置。
被动方的记录由hibernate负责读取,之后存放在主控方指定的collection类型属性中。collection类型为hibernate所自定义的,继承了java的基础collection类型。
单向一对多可能会造成约束违例,例如not null。
双向一对多的关系可以避免约束违例和提高性能,还可以在任意一方访问关联的一方。
1.控制反转,由关联的关系去维护。
11.Inverse 和cascade的区别:
Inverse 指的是关联关系的控制方向,cascade指的是层级之间的连锁操作。
3.多对多关联:需要引入中间表。
12.数据检索:
1.criteria query :是面向对象化的设计,把数据查询条件封装为一个对象。
Criteria 本质为一个容器,具体的查询条件需要通过criteria.add添加到criteria实例中。
2.example类实现了criteria接口。Example的作用是:根据已有对象,查找属性与之相符合的其他对象。
3.detachedCriteria: 脱离session实例独立存在,生命周期与session实例无关,需要使用时再与session相互绑定。
4.hql 查询:相似sql。使用hql delete/update语句的时候,必须注意它们对缓存策略的影响。不同点,sql面向的是二维的结构化数据,hql则面向数据对象。
5.引用查询:把sql语句配置在文件中,需要的时候再读取。
6.sql查询:hibernate中的sql查询,resultset与实体的映射将由hibernate自动完成。
7.存储过程的查询;
8.自定义持久化实现。
13.数据加载方式:(针对关联数据)
1即时加载:实体数据加载完成后,立即加载关联的数据,可能多条sql语句读取关联数据。
2.延迟加载:实体加载时,有关联的数据被访问时再加载读取。
3.预先加载:与即时加载类似,实体与关联数据是通过一条sql语句同时读取。
4.批量加载:即时和延迟加载可以进行性能上的调优。
14.vo(value object)对象与po(persistent object)对象:以实体对象是否被纳入hibernate实体管理容器的立场区分。
Vo与Po的区别:
15.实体身份识别:
1.引用比较(==):判断俩个变量是否引用了同一个对象实例。
2.内容比较 (equals):判断俩个对象所包含的数据是否相同。
3.hashCode方法:集合容器常用的比较对象是否相等。集合容器对象,会先比较hashcode码,再比较equals方法。
unsaved-value:hibernate根据该值来判断(Vo)对象是否需要保存,针对插入语句。(针对级联,没有显示保存语句的操作)
16.延迟加载:
1、实体对象。
2、集合
3、实体属性。
17.lifecyle与validatable :对实体对象的CRUD操作进行捕获并执行相应的处理。如同数据层的triger触发器的实现。
18.interceptor接口:定义了hibernate中通用的拦截机制。Session创建时指定加载相应的拦截器,此session的持久化动作都先经该拦截器捕获处理。