Hibernate梳理1

0

它是一种成熟的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:
clipboard.png

重启
空白处点new other 出现下图表示插件安装成功
clipboard.png
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 文件(关系映射文件)。

clipboard.png

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 的特定方法能使对象从一个状态转换到另一个状态。
clipboard.png

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 应用程序访问数据库的频率。

如:
clipboard.png
只会向数据库发送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

设置事务的隔离级别

你可能感兴趣的

载入中...