java 私塾随堂笔记——Hibernate(下)
java 私塾随堂笔记——Hibernate(下)第四章 Basic O/R Mapping
一.
1.hibernate-mapping
<hibernate-mapping
schema="schemaName"
default-cascade="cascade_style"
default-lazy="true|false"
/>
schema (可选): 数据库schema的名称。
default-cascade (可选 - 默认为 none): 默认的级联风格。
default-lazy (可选 - 默认为 true): 指定了未明确注明lazy属性的Java属性和集合类,Hibernate会采取什么样的默认加载风格。
2.Class
<class
name="ClassName"
table="tableName"
dynamic-update="true|false"
dynamic-insert="true|false"
optimistic-lock="none|version|dirty|all"
lazy="true|false"
/>
name (可选): 持久化类(或者接口)的Java全限定名。 如果这个属性不存在, Hibernate将假定这是一个非POJO的实体映射。
table (可选 - 默认是类的非全限定名): 对应的数据库表名。
dynamic-update (可选, 默认为 false): 指定用于UPDATE 的SQL将会在运行时动态生成,并且只更新那些改变过的字段。
dynamic-insert (可选, 默认为 false): 指定用于INSERT的 SQL 将会在运行时动态生成,并且只包含那些非空值字段。
optimistic-lock(乐观锁定)(可选,默认是version): 决定乐观锁定的策略。
lazy (可选): 通过设置lazy="false", 所有的延迟加载(Lazy fetching)功能将被全部禁用(disabled)。
如果你打开了dynamic-update,你可以选择几种乐观锁定的策略:
version(版本检查) 检查version/timestamp字段
all(全部) 检查全部字段
dirty(脏检查)只检察修改过的字段
none(不检查)不使用乐观锁定
3. id
被映射的类必须定义对应数据库表主键字段。大多数类有一个JavaBeans风格的属性,为每一个实例包含唯一的标识。<id> 元素定义了该属性到数据库表主键字段的映射。
<id
name="propertyName"
type="typename"
column="column_name"
</id>
name (可选): 标识属性的名字。
type (可选): 标识Hibernate类型的名字。
column (可选 - 默认为属性名): 主键字段的名字。
4. Generator
可选的<generator>子元素是一个Java类的名字, 用来为该持久化类的实例生成唯一的标识。
<id name="id" type="long" column="cat_id">
<generator class="org.hibernate.id.TableHiLoGenerator">
<param name="table">uid_table</param>
<param name="column">next_hi_value_column</param>
</generator>
</id>
assigned
让应用程序在save()之前为对象分配一个标示符。这是 <generator>元素没有指定时的默认生成策略。
5. <property>元素为类定义了一个持久化的,JavaBean风格的属性。
<property
name="propertyName"
column="column_name"
type="typename"
/>
name: 属性的名字,以小写字母开头。
column (可选 - 默认为属性名字): 对应的数据库字段名。 也可以通过嵌套的<column>元素指定。
type (可选): 一个Hibernate类型的名字。
第五章 与对象共事
1. Hibernate对象状态(object states)
瞬时(Transient) - 由new操作符创建,且尚未与Hibernate Session 关联的对象被认定为瞬时(Transient)的。
持久(Persistent) - 持久(Persistent)的实例在数据库中有对应的记录,并拥有一个持久化标识(identifier)。
脱管(Detached) - 与持久(Persistent)对象关联的Session被关闭后,对象就变为脱管(Detached)的。
2. 装载对象
load和get
区别:
a.load先查内存,有就用,没有再查数据库。Get直接查数据库。
b.查数据库没有之后,load报例外,get返回null。
3. 修改持久对象
先load出对象,在对其作修改,然后调用flush();
4. 修改脱管(Detached)对象
Hibernate通过提供Session.update()或Session.merge() 重新关联脱管实例的办法来支持这种模型。
5. 自动状态检测
Hibernate的用户曾要求一个既可自动分配新持久化标识(identifier)保存瞬时(transient) 对象,又可更新/重新关联脱管(detached)实例的通用方法。 saveOrUpdate()方法实现了这个功能。
6. 使用Session.delete()会把对象的状态从数据库中移除。
7.拼接hql字符串进行查询
*Hinbernate中的缓存问题
一、一级缓存
一级缓存的生命周期和session的生命周期一致,当前sessioin一旦关闭,一级缓存就消失,因此一级缓存也叫session级的缓存或事务级缓存,一级缓存只存实体对象的 ,它不会缓存一般的对象属性(查询缓存可以),即当获得对象后,就将该对象的缓存起来,如果在同一session中如果再去获取这个对象时,它会先判断缓存中有没有该对象的ID,如果有就直接从缓存中取出,反之则去数据库中取,取的同时将该对象的缓存起来,有以下方法可以支持一级缓存:
* get()
* load()
* iterate(查询实体对象)
其中 Query 和Criteria的list() 只会缓存,但不会使用缓存(除非结合查询缓存)。
二、二级缓存
二级缓存也称进程级的缓存或SessionFactory级的缓存,二级缓存可以被所有的session共享,二级缓存的生命周期和SessionFactory的生命周期一致。hibernate为实现二级缓存,只提供二级缓存的接口供第三方来实现。二级缓存也是缓存实体对象 ,其实现原理与一级缓存的差不多吧,其方法与一级的相同,只是缓存的生命周期不一样而已:
* get()
* load()
* iterate(查询实体对象)
其中 Query 和Criteria的list() 只会缓存,但不会使用缓存(除非结合查询缓存)。
什么样的数据适合存放到第二级缓存中?
1、很少被修改的数据
2、不是很重要的数据,允许出现偶尔并发的数据
3、不会被并发访问的数据
4、参考数据
不适合存放到第二级缓存的数据?
1、经常被修改的数据
2、财务数据,绝对不允许出现并发
3、与其他应用共享的数据。
*各种控制的流程
1.save(model)
★to→po
★事务判断要不要提交。我们写了t.commit(),他才会瓶sql往下走。
★通过po得到一个全路径拼出model.hbm.xml,到.cfg.xml中找到hbm.xml。
★动态拼sql。
★得到连接。
★执行JDBC。
2.update(model)注意:dynamic-update只生成改过的字段
★to→po(dynamic-updatehuixian load一遍)
★t.commit
★po找到model.hbm.xml
★拼sql
★得到连接
★执行JDBC
(merge其实是借用po的表,装to,因为session实力池中相同主键的实例只有一个)
3.get(model类,主键值;)(双主键时,传一个封装双主键的主键类)
★依据model类找到model类.hbm.xml
★动态拼sql
★执行sql的rs
★rs→类实例(反射技术)
load(model类,主键值;)在以上步骤前加一步:在内存中查找
4.query
★词法分析(HQL)得到类名
★类名→model.hbm.xml
★动态拼sql
★会有两个结果:
①object[]
②各个类实例的集合
★返回若cfg.xml中两个model名称相同,路径不同,则在xml中的类名部分要是全路径
java 私塾官网有完整笔记下载,也有课堂实录学习视频:www.javass.cn/javapeixunzlxz/zlxz.html
页:
[1]