它是一种成熟的ORMORM(Object/Relation Mapping对象/关系映射)框架。完成对象的持久化操作(包括保存、更新、删除、查询、加载)。
hibernate源码 ORM
采用元数据来描述对象-关系映射细节, 元数据通常采用 XML 格式, 并且存放在专门的对象-关系映射文件中。
与myBatis对比:
myBatis 相比 Hibernate 灵活高,运行速度快,但开发速度慢,不支持纯粹的面向对象操作,需熟悉sql语句,并且熟练使用sql语句优化功能。
hibernate的优势在于它消除了那些针对特定数据库厂商的 SQL 代码,允许开发者采用面向对象的方式来操作关系数据库。
其他ORM框架还有:
TopLink
OJB
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
。
站在持久化的角度, Hibernate 把对象分为 4 种状态: 持久化状态, 临时状态, 游离状态, 删除状态
。
OID 不为 null;
位于 Session 缓存中;
若在数据库中已经有和其对应的记录, 持久化对象和数据库中的相关记录对应;
Session 在 flush 缓存时, 会根据持久化对象的属性变化, 来同步更新数据库;
在同一个 Session 实例的缓存中, 数据库表中的每条记录只对应唯一的持久化对象;
在使用代理主键的情况下, OID 通常为 null;
不处于 Session 的缓存中;
在数据库中没有对应的记录;
在数据库中没有和其 OID 对应的记录;
不再处于 Session 缓存中;
一般情况下, 应用程序不该再使用被删除的对象。
OID 不为 null;
不再处于 Session 缓存中;
一般情况需下, 游离对象是由持久化对象转变过来的, 因此在数据库中可能还存在与它对应的记录。
使用 Hibernate 进行数据持久化操作,通常有如下步骤:
获取 Configuration 对象
获取 SessionFactory 对象
获取 Session,打开事务
用面向对象的方式操作数据库
关闭事务,关闭 Session
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是生成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 是应用程序与数据库之间交互操作的一个单线程对象,是 Hibernate 运作的中心,所有持久化对象必须在 session 的管理下才可以进行持久化操作。此对象的生命周期很短。Session 对象有一个一级缓存,显式执行 flush 之前,所有的持久层操作的数据都缓存在 session 对象处。 相当于 JDBC 中的 Connection
。
持久化类与 Session 关联起来后就具有了持久化的能力。
Session
的特定方法能使对象从一个状态转换到另一个状态。
Session 类的方法:
取得持久化对象的方法: get()、 load()
持久化对象都得保存,更新和删除:save()、update()、saveOrUpdate()、delete()
开启事务: beginTransaction().
管理 Session 的方法:isOpen()、flush()、clear()、evict()、 close()等
完成以下操作:
把 News 对象加入到 Session 缓存中, 使它进入持久化状态;
选用映射文件指定的标识符生成器, 为持久化对象分配唯一的 OID. 在 使用代理主键的情况下, setId() 方法为 News 对象设置 OID 使无效的;
计划执行一条 insert 语句:在 flush 缓存的时候。
Hibernate 通过持久化对象的 OID 来维持它和数据库相关记录的对应关系. 当 News 对象处于持久化状态时, 不允许程序随意修改它的 ID!
persist() 和 save() 区别:
当对一个 OID 不为 Null 的对象执行 save() 方法时, 会把该对象以一个新的 oid 保存到数据库中; 但执行 persist() 方法时会抛出一个异常.
都可以根据跟定的 OID 从数据库中加载一个持久化对象。
区别:
当数据库中不存在与 OID 对应的记录时, load() 方法抛出 ObjectNotFoundException 异常, 而 get() 方法返回 null
两者采用不同的延迟检索策略: load 方法支持延迟加载策略
,而 get 不支持。
若希望 Session 仅当修改了 News 对象的属性时, 才执行 update() 语句, 可以把映射文件中 <class> 元素的 select-before-update 设为 true. 该属性的默认值为 false。
当 update() 方法关联一个游离对象时, 如果在 Session 的缓存中已经存在相同 OID 的持久化对象, 会抛出异常。
当 update() 方法关联一个游离对象时, 如果在数据库中不存在相应的记录, 也会抛出异常。
在 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 tx = session.beginTransaction();
对于增删改是必须有事务的。
增时,不开事务增不了数据(不会报错),但id会有裂缝。
常用方法:
commit():提交相关联的session实例
rollback():撤销事务操作
wasCommitted():检查事务是否提交
hbm2ddl.auto
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
。
是否将 SQL 转化为格式良好的 SQL . 取值 true | false
。
Using 'MySQL5InnoDBDialect' works with 5.1 and 5.5.
设置事务的隔离级别