一.是什么:
Hibernate是轻量级的ORM框架。
1.ORM(ORMapping)
Object |
Relation DB |
Mapping |
JDBC |
Hibernate做的就是中间的部分
Application程序面向的是Object,操作的是Object,所以要吧DB中的数据映射成 Object它才能使用
2.Object与RDB之间映射关系的特点(Hibernate中)
(1)类跟表相对应 (UserModel对应于tbl_user)
(2)类的属性跟表的字段相对应
(3)类的实例与表中具体的一条记录相对应
(4)一个类可以对着多个表,一个表也可以对应对个类
(5)DB中的表可以没有主键,但是Object中必须设置主键作为PK字段,不为空且唯一。所以DB跟Object并不是一一映射的
(6)外键:DB中表与表之间的关系映射成为Object之间的关系。
(7)table中字段的个数和名称可以和Object中定义的不一样,在部署连接文件中将两者连接起来即可
二.能干什么?
Hibernate不仅仅管理java类到数据库表的映射,还提供数据查询和获取数据的方法,可以大幅度减少开发时人工使用SQL和JDBC数据处理的时间。
三.有什么?
SessionFactory
针对单个数据库映射经过编译后的内存对象,是线程安全的。他是生成Session的工厂
Session
表示应用程序与持久层之间交互操作的一个单线程对象。
持久化对象
带有持久化状态的,具有业务功能的单线程对象。
瞬时及托管对象
那些没有与session关联的持久化类实例。
事务Transaction
应用程序用来指定原子操作单元范围的对象。
ConnectionProvider连接池
生成JDBC连接的工厂。
TransactioinFactory
生成Transaction对象实例的工厂。
四.怎么用?
1.构建环境(建工程引包)
2.建model建table
3.做配置文件
Hibernate文件分为两类 ***.cfg.xml ***.hbm.xml
***.cfg.xml :
a.缺省名称为 hibernate.cfg.xml
b.存放在当前classes的根目录下
c.有如下四部分配置与DB连接
可选配置(dialect) 资源文件注册 (hbm.xml) 二级缓存
***.hbm.xml
a.与被描述的类同名 UserModel.hbm.xml
b.存放位置必须与所描述类存放在同一文件夹下
c.四部分配置类和表的映射
主键的映射
类的属性和DB中字段的映射
关系的映射
*类中默认的cfg.xml文件是hibernate.cfg.xml若改变名称,在类中使用时要指出
new Configuration().configure(“cc.cfg.xml”).buildSessionFactory;
*标准的JEE规范是通过服务器来实现的
*Hibernate 帮助我们做的是数据库中数据的持久化。
我们要做的是 Object(App中) Table(DB中) Client(App中) xml(Hibernate)
*Blob存储多大4G的非结构化二进制数据
Clob用来存储多大4G的字符数据
第三部分 JDBC连接
一. *.cfg.xml中JDBC连接最重要的设置
<property name=”connection.driver.class”>……..</property>
<property name=”connection.url”>……..</property>
<property name=”connection.userName”>……..</property>
<property name=”connection.password”>……..</property>
二.可选的配置属性
1.<property name=”dialect”>org.hibernate.dialect.Oracle9iDialect</property>(必选的)
2.<property name=”show-sql”>true</property>
3.hibernate.connection.isolation设置JDBC事务隔离级别(建议选)
4.hibernate.transaction.factory-class想改变hibernate事务实现机制时用。
事务策略配置有三个标准的选择:
org.hibernate.transaction.JDBCTransactionFactory 授权给数据库事务
org.hibernate.JTATransactionFactory JTA能做分布事务
org.hibernate.transaction. CMTransactionFactory
5.jta.userTransaction 若四中选择的是JTA则这个必须选择
6.hibernate.hbmzddl.auto 自动生成表
三.JEE应用程序服务器的集成
1.container-managerd datasource:Hibernate能使用通过容器管理,并有JNDI提供的JDBC 连接
2.自动JNDI绑定:Hibernate可以将SessionFactory绑定到JNDI
3.JTAsession绑定:HibernateSession 可以自动绑定到JTA事务作用的范围,只需简单的从JNDI中查找sessionFactory并获得当前的Session
4.JMX部署
第四章 Persistence Class
一.POJO
1.四条主要规则
实现一个默认的(即无参数的)构造方法(constructor)
提供一个标识属性(identifier property)
使用非final的类
为持久化字段声明访问器(accessors)和是否可变的标志(mutators)
2. 实现继承(Inheritance)
3. 实现equals()和hashCode()
4. Hibernate也支持动态模型 (在运行期使用Map的Map)和象DOM4J的树模型那样的实体表示。使用这种方法,你不用写持久化类,只写映射文件就行了。
第五章 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中的类名部分要是全路径