共计 5887 个字符,预计需要花费 15 分钟才能阅读完成。
它是一种成熟的 ORMORM(Object/Relation Mapping 对象 / 关系映射)框架。完成对象的持久化操作(包括保存、更新、删除、查询、加载)。
hibernate 源码
ORM
采用元数据来描述对象 - 关系映射细节, 元数据通常采用 XML 格式, 并且存放在专门的对象 - 关系映射文件中。
与 myBatis 对比:
myBatis 相比 Hibernate 灵活高,运行速度快,但开发速度慢,不支持纯粹的面向对象操作,需熟悉 sql 语句,并且熟练使用 sql 语句优化功能。
hibernate 的优势在于它消除了那些针对特定数据库厂商的 SQL 代码,允许开发者采用面向对象的方式来操作关系数据库。
其他 ORM 框架还有:
TopLink
OJB
eclipse 开发环境下使用 hibernate
1.eclipse 安装插件,以便生成配置文件
Help > Install New Software… > Work with:
http://download.jboss.org/jbo…
Then select the individual features that you want to install:
重启
空白处点 new other 出现下图表示插件安装成功
xml 配置文件的 dtd 会关联上
2. 创建 maven 项目,配置 pom 文件
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>4.2.5.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-ehcache</artifactId>
<version>4.2.5.Final</version>
</dependency>
3.resource/ 目录下,利用插件创建hibernate.cfg.xml
,完成 hibernate 配置,包括数据库的基本信息、数据库方言、自动生成数据表的策略还有关联的 .hbm.xml
文件(关系映射文件)。
jdbc:mysql:///test
写法怎么来
jdbc:mysql://localhost:3306/test
4. 创建持久化类,即实体类(需要无参构造器),之后利用 hibernate 插件创建 .hbm.xml
对象 - 关系映射文件,每个实体类对应一个。
5. 通过 Hibernate API 编写访问数据库的代码
关于持久化类
1. 提供一个无参的构造器: 使 Hibernate 可以使用 Constructor.newInstance() 来实例化持久化类
2. 提供一个标识属性(identifier property): 通常映射为数据库表的主键字段. 如果没有该属性,一些功能将不起作用,如:Session.saveOrUpdate()。OID
:为了在系统中能够找到所需对象,需要为每一个对象分配一个唯一的标识号。在关系数据库中称之为主键,而在对象术语中,则叫做对象标识(Object identifier-OID)。
自行搜索Hibernate 主键生成策略
3. 为类的持久化类字段声明访问方法(get/set): Hibernate 对 JavaBeans 风格的属性实行持久化。
4. 使用非 final 类: 在运行时生成代理是 Hibernate 的一个重要的功能. 如果持久化类没有实现任何接口, Hibnernate 使用 CGLIB 生成代理. 如果使用的是 final 类, 则无法生成 CGLIB 代理.
5. 重写 eqauls 和 hashCode 方法: 如果需要把持久化类的实例放到 Set 中(当需要进行关联映射时), 则应该重写这两个方法。
Hibernate 采用 XML 格式的文件来指定对象和关系数据之间的映射,在运行时 Hibernate 将根据这个映射文件来生成各种 SQL 语句,映射文件的扩展名为 .hbm.xml
。
持久化对象的 4 种状态
站在持久化的角度, Hibernate 把对象分为 4 种状态: 持久化状态, 临时状态, 游离状态, 删除状态
。
持久化对象(也叫“托管”)(Persist):
OID 不为 null;
位于 Session 缓存中;
若在数据库中已经有和其对应的记录, 持久化对象和数据库中的相关记录对应;
Session 在 flush 缓存时, 会根据持久化对象的属性变化, 来同步更新数据库;
在同一个 Session 实例的缓存中, 数据库表中的每条记录只对应唯一的持久化对象;
临时对象(Transient):
在使用代理主键的情况下, OID 通常为 null;
不处于 Session 的缓存中;
在数据库中没有对应的记录;
删除对象(Removed)
在数据库中没有和其 OID 对应的记录;
不再处于 Session 缓存中;
一般情况下, 应用程序不该再使用被删除的对象。
游离对象(也叫”脱管”)(Detached):
OID 不为 null;
不再处于 Session 缓存中;
一般情况需下, 游离对象是由持久化对象转变过来的, 因此在数据库中可能还存在与它对应的记录。
hibernate 访问数据库 api
使用 Hibernate 进行数据持久化操作,通常有如下步骤:
获取 Configuration 对象
获取 SessionFactory 对象
获取 Session,打开事务
用面向对象的方式操作数据库
关闭事务,关闭 Session
关于 Configure 类
Configuration 类负责管理 Hibernate 的配置信息。包括如下内容:
Hibernate 运行的底层信息:数据库的 URL、用户名、密码、JDBC 驱动类,数据库 Dialect, 数据库连接池等(对应 hibernate.cfg.xml 文件), 还有持久化类与数据表的映射关系(*.hbm.xml
文件)。
创建 Configuration 的两种方式:
属性文件是 hibernate.properties
时:Configuration cfg = new Configuration();
属性文件是 Xml 文件 hibernate.cfg.xml
时(一般是这种):Configuration cfg = new Configuration().configure();
Configuration 的 configure 方法还支持带参数的访问:File file = new File(“simpleit.xml”);
Configuration cfg = new Configuration().configure(file);
关于 SessionFactory 对象
针对单个数据库映射关系经过编译后的内存镜像,是线程安全的。
SessionFactory 对象一旦构造完毕,即被赋予特定的配置信息。
SessionFactory 是生成 Session 的工厂。
构造 SessionFactory 很消耗资源,一般情况下一个应用中只初始化一个 SessionFactory 对象。
Hibernate4 新增了一个 ServiceRegistry 接口,所有基于 Hibernate 的配置或者服务都必须统一向这个 ServiceRegistry 注册后才能生效
Hibernate4 中创建 SessionFactory 的步骤:
SessionFactory sessionFactory = null;
//1). 创建 Configuration 对象: 对应 hibernate 的基本配置信息和 对象关系映射信息。// 读取 cfg.xml
Configuration configuration = new Configuration().configure();
//4.0 之前这样创建
//sessionFactory = configuration.buildSessionFactory();
//2). 创建一个 ServiceRegistry 对象: hibernate 4.x 新添加的对象
//hibernate 的任何配置和服务都需要在该对象中注册后才能有效.
ServiceRegistry serviceRegistry =
new ServiceRegistryBuilder().applySettings(configuration.getProperties())
.buildServiceRegistry();
//3).
sessionFactory = configuration.buildSessionFactory(serviceRegistry);
关于 session 对象
Session 是应用程序与数据库之间交互操作的一个单线程对象,是 Hibernate 运作的中心,所有持久化对象必须在 session 的管理下才可以进行持久化操作。此对象的生命周期很短。Session 对象有一个一级缓存,显式执行 flush 之前,所有的持久层操作的数据都缓存在 session 对象处。相当于 JDBC 中的 Connection
。
持久化类与 Session 关联起来后就具有了持久化的能力。
Session
的特定方法能使对象从一个状态转换到另一个状态。
Session 类的方法:
取得持久化对象的方法:get()、load()
持久化对象都得保存,更新和删除:save()、update()、saveOrUpdate()、delete()
开启事务: beginTransaction().
管理 Session 的方法:isOpen()、flush()、clear()、evict()、close()等
save()
完成以下操作:
把 News 对象加入到 Session 缓存中, 使它进入持久化状态;
选用映射文件指定的标识符生成器, 为持久化对象分配唯一的 OID. 在 使用代理主键的情况下, setId() 方法为 News 对象设置 OID 使无效的;
计划执行一条 insert 语句:在 flush 缓存的时候。
Hibernate 通过持久化对象的 OID 来维持它和数据库相关记录的对应关系. 当 News 对象处于持久化状态时, 不允许程序随意修改它的 ID!
persist() 和 save() 区别:
当对一个 OID 不为 Null 的对象执行 save() 方法时, 会把该对象以一个新的 oid 保存到数据库中; 但执行 persist() 方法时会抛出一个异常.
get()、load()
都可以根据跟定的 OID 从数据库中加载一个持久化对象。
区别:
当数据库中不存在与 OID 对应的记录时, load() 方法抛出 ObjectNotFoundException 异常, 而 get() 方法返回 null
两者采用不同的延迟检索策略:load 方法支持延迟加载策略
,而 get 不支持。
update()
若希望 Session 仅当修改了 News 对象的属性时, 才执行 update() 语句, 可以把映射文件中 <class> 元素的 select-before-update 设为 true. 该属性的默认值为 false。
当 update() 方法关联一个游离对象时, 如果在 Session 的缓存中已经存在相同 OID 的持久化对象, 会抛出异常。
当 update() 方法关联一个游离对象时, 如果在数据库中不存在相应的记录, 也会抛出异常。
Session 缓存(一级缓存)
在 Session 接口的实现中包含一系列的 Java 集合, 这些 Java 集合构成了 Session 缓存,只要 Session 实例没有结束生命周期, 且没有清理缓存,则存放在它缓存中的对象也不会结束生命周期。
Session 缓存可减少 Hibernate 应用程序访问数据库的频率。
如:
只会向数据库发送 1 条 SQL
操作缓存之 flush():
Session 按照缓存中对象的属性变化来同步更新数据库 (update、insert 语句)
什么时候会执行 flush():
1)显式调用 Session 的 flush() 方法
2) 查得一个对象后,修改该对象的属性,执行 transaction.commit(),该方法有调用 flush()
3)当应用程序执行一些查询 (HQL, Criteria) 操作时,怕缓存中持久化对象的属性已经发生了变化,会先 flush 缓存更新表,以保证查询结果能够反映持久化对象的最新状态。
4)如果对象使用 native 生成器生成 OID, 那么当调用 Session 的 save() 方法保存对象时, 会立即执行向数据库插入该实体的 insert 语句.
commit() 和 flush() 方法的区别:flush 执行一系列 sql 语句,但不提交事务;commit 方法先调用 flush() 方法,然后提交事务. 意味着提交事务意味着对数据库操作永久保存下来。
也可自行设定刷新缓存的时间点。
操作缓存之 reflush():
Session 按照数据库同步更新缓存对象(select 语句)
clear(): 清理缓存
数据库的隔离级别
?
关于 transaction 对象
代表一次原子操作,它具有数据库事务的概念。所有持久层都应该在事务管理下进行,即使是只读操作。
Transaction tx = session.beginTransaction();
对于增删改是必须有事务的。
增时,不开事务增不了数据(不会报错),但 id 会有裂缝。
常用方法:
commit(): 提交相关联的 session 实例
rollback(): 撤销事务操作
wasCommitted(): 检查事务是否提交
Hibernate 配置文件常用配置项:
hbm2ddl.auto
指定自动生成数据表的策略。该属性可帮助程序员实现正向工程, 即由 java 代码生成数据库脚本, 进而生成具体的表结构.。取值 create | update | create-drop | validate
create
: 会根据 .hbm.xml 文件来生成数据表, 但 是每次运行都会删除上一次的表
, 重新生成表, 哪怕二次没有任何改变,慎用!create-drop
: 会根据 .hbm.xml 文件生成表, 但是 SessionFactory 一关闭, 表就自动删除
,慎用!update
: 最常用
的属性值,也会根据 .hbm.xml 文件生成表, 但若 .hbm.xml 文件和数据库中对应的数据表的表结构不同, Hiberante 将更新数据表结构(一般是新增列),但 不会删除已有的行和列
。validate
: 会和数据库中的表进行比较, 若 .hbm.xml 文件中的 列在数据表中不存在,则抛出异常 HibernateException:Missing colume
。
format_sql
是否将 SQL 转化为格式良好的 SQL . 取值 true | false
。
dialect
Using 'MySQL5InnoDBDialect' works with 5.1 and 5.5.
hibernate.connection.isolation
设置事务的隔离级别