Hibernate 学习教程
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Hibernate 学习教程相关的知识,希望对你有一定的参考价值。
Hibernate 学习大纲
6. 级联(cascade),反转(inverse),延迟加载,检索策略,和set元素介绍 6
Hibernate 入门
什么是ORM
ORM(Object/Relationship Mapping) 对象/关系映射;
利用面向对象思想编写的数据库应用程序最终都是把对象信息保存到关系型数据库中,于是要编写很多和底层数据相关的的SQL语句。
Hibernate介绍
Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,是一个全自动的orm框架,hibernate可以自动生成SQL语句,自动执行,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库。 Hibernate可以应用在任何使用JDBC的场合,既可以在Java的客户端程序使用,也可以在Servlet/JSP的Web应用中使用,最具革命意义的是,Hibernate可以在应用EJB的J2EE架构中取代CMP,完成数据持久化的重任。
Hibernate环境搭建
- 拷贝Hibernate基本jar包
Maven
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>4.3.11.Final</version>
</dependency>
<dependency>
<groupId>antlr</groupId>
<artifactId>antlr</artifactId>
<version>2.7.7</version>
</dependency>
<dependency>
<groupId>org.apache.avro</groupId>
<artifactId>avro</artifactId>
<version>1.6.3</version>
</dependency>
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>1.6.1</version>
</dependency>
<dependency>
<groupId>org.hibernate.common</groupId>
<artifactId>hibernate-commons-annotations</artifactId>
<version>4.0.2.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>4.2.2.Final</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.2</version>
</dependency>
<dependency>
<groupId>org.javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.15.0-GA</version>
</dependency>
<dependency>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging</artifactId>
<version>3.1.0.GA</version>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-core</artifactId>
<version>3.6.2</version>
</dependency>
<dependency>
<groupId>com.thoughtworks.paranamer</groupId>
<artifactId>paranamer</artifactId>
<version>2.3</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.6.1</version>
</dependency>
<dependency>
<groupId>org.xerial.snappy</groupId>
<artifactId>snappy-java</artifactId>
<version>1.0.4.1</version>
</dependency>
实体映射文件
Hibernate 的内置映射类型通常使用和Java类型相同的名字,它能够把Java基本类型,Java时间额日期类型,Java大对象类型及JDK中常用的Java类型映射到相应的标准SQL类型
Hibernate映射类型
Java类型
标准SQL类型
大小
integer或int
int或者java.lang.Integer
INTEGER
4字节
long
long或者java.lang.Long
BIGINT
8字节
short
short或者java.lang.Byte
SMALLINT
2字节
byte
byte或者java.lang.Byte
TINYINT
1字节
float
float或者java.lang.Float
LOAT
4字节
double
double或者java.lang.Double
DOUBLE
8字节
character
char或者java.lang.Character
或者java.lang.String
CHAR(1)
定长字符
string
java.lang.String
ARCHAR
可变字符串
boolean
boolea或者java.lang.Boolean
BIT
布尔类型
yes_no
boolea或者java.lang.Boolean
CHAR(1)(Y/N)
布尔类型
true_false
boolea或者java.lang.Boolean
CHAR(1)(Y/N)
布尔类型
Java时间和日期类型的Hibernate映射类型
映射类型
Java类型
标准SQL类型
描述
date
java.util.Date或者java.sql.Date
DATE
代表日期,形式为:YYYY-MM-DD
time
java.util.Date或者java.sql.Time
TIME
代表时间,形式为:HH:MM:SS
timestamp
java.util.Date或者java.sql.Timestamp
TIMESTAMP
代表时间和日期,形式为:YYYY-MM-DD HH:MM:SS
calendar
java.util.Calendar
TIMESTAMP
代表时间和日期,形式为:YYYY-MM-DD HH:MM:SS
calendar_date
java.util.Calendar
DATE
代表日期,形式:YYYY-MM-DD
Java大对象类型的Hibernate映射类型
映射类型
Java类型
标准SQL类型
MySQL类型
Oracle类型
binary
byte[]
VARBINARY或者BLOB
BLOB
BLOB
text
java.lang.String
CLOB
TEXT
CLOB
serializable
实现java.io.Serializable接口的任意一个Java类
VARBINARY或者BLOB
BLOB
BLOB
clob
java.sql.Clob
CLOB
TEXT
CLOB
blob
java.sql.Blob
BLOB
BLOB
BLOB
JDK自带的个别Java类的Hibernate映射类型
映射类型
Java类型
标准SQL类型
class
java.lang.Class
VARCHAR
locale
java.util.Locale
VARCHAR
time
java.util.TimeZone
VARCHAR
currency
java.util.Currency
VARCHAR
Hibernate操作数据库
创建SessionFactory
SessionFactory sf = null;
- 读取配置文件并解析
Configuration config = new Configuration.configure();
- 获得SessionFactory 【Hibernate 4.0 之前的方式】
sf = config.buildSessionFaction();
③ 获得SessionFactory 【4.0 之后的方式】
- 创建一个ServerRegistry对象【Hibernate的任何配置和服务都需要在该对象注册后才有效】
ServiceRegistry sr = new ServiceRegistryBuilder().applySettings(config.getProperties()).buildServiceRegistry();
sf = config.buildSessionFactory(sr);
创建一个Session
Session session = sf.openSession();
开启事务
Transaction tran = session.beginTransaction();
执行数据库操作
方法
方法说明
save()
插入
update()
修改
saveOrUpdate()
修改或者更新
get()
查询数据不存在的时候会报错
load()
延迟加载数据,可以再class中配置lazy = false 修改为立即加载
list()
查询
iteratr()
查询
提交事务
tran.commit();
释放资源
session.close();
sf.close();
list,iterate区别
- 使用list()方法获取查询结果,每次发出一条查询语句,获取全部数据
- 使用iterate()方法获取查询结果,先发出一条SQL 语句用来查询满足条件数据的id,然后依次按这些id 查询记录,也就是要执行N+1 条SQL 语句(N 为符合条件的记录数)
- list()方法将不会在缓存中读取数据,它总是一次性的从数据库中直接查询所有符合条件的数据,同时将获取的数据写入缓存
- iterate()方法则是获取了符合条件的数据的id 后,首先根据id 在缓存中寻找符合条件的数据,若缓存中无符合条件的数据,再到数据库中查询
Hibernate常用接口和类介绍
- Configuration 类
负责管理Hibernate的配置信息,
- SessionFactory 接口
- Session 接口
- Transaction 接口
Session 接口专题
1、作用:提供基本的保存,删除,更新,和加载Java对象
2、什么是清理缓存:
Session能够在某些时间点,按照缓存中对象的变化来执行相关的SQL语句,来同步更新数据库,这一过程别称为清理缓存(flush)
3、SessionFactory是线程安全的(可以多个对象共用同一个对象)。而Session不是线程安全的。
为了解决Session线程不安全我们采用ThreadLocal方案。
ThreadLocal 模式的解决方案:
ThreadLocal并不是一个线程的本地实现,也就是说它不是一个Thread,而是Thread local variable(线程局部变量)。它的作用就是为每一个使用这个变量的线程提供一个变量的副本,并且每一个线程都可以独立地改变自己的副本,而不会和其它线程的副本冲突。
ThreadLocal模式实例代码:
public void getSession() {
Configuration cfg = new Configuration().configure();
SessionFactory sf = cfg.buildSessionFactory();
session = sf.openSession();
}
//创建ThreadLocal对象
private static final ThreadLocal threadLodacl = new ThreadLocal();
public void getSession() {
Configuration cfg = new Configuration().configure();
SessionFactory sf = cfg.buildSessionFactory();
//session = sf.openSession();
//解决session线程非安全的方式
this.session = (Session) threadLodacl.get();
if(session == null){
this.session = sf.openSession();
threadLodacl.set(this.session);
}
}
4、获取session的两种方式介绍
- getCurrentSession创建的Session会绑定到当前线程,而openSession不会
- getCurrentSession创建的Session会在事务回滚或者事务提交后自动关闭,而openSession创建的必须手动关闭(调用Session的cloe()方法)
- getCurrentSession使用方法
- 当使用本地使唔时(jdbc事务)
需要在hibernate.cfg.xml文件的<session-factor>节点添加:
<property name="hibernate.current_session_context_class">thread</property>
- 当使用的是全局使唔时(jta事务)
<property name="hibernate.current_session_context_class">jta</property>
注意:如果使用了getCurrentSession方法又没有在配置中配置以上方法时程序编译无误,但是运行汇报如下错误。
Exception in thread "main" org.hibernate.HibernateException: No CurrentSessionContext configured!
at org.hibernate.impl.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:620)
5、Session的get()与load()
6、Session接口常见方法
序号
Session 方法及说明
1
Transaction beginTransaction()
开始工作单位,并返回关联事务对象。2
void cancelQuery()
取消当前的查询执行。3
void clear()
完全清除该会话。4
Connection close()
通过释放和清理 JDBC 连接以结束该会话。5
Criteria createCriteria(Class persistentClass)
为给定的实体类或实体类的超类创建一个新的 Criteria 实例。6
Criteria createCriteria(String entityName)
为给定的实体名称创建一个新的 Criteria 实例。7
Serializable getIdentifier(Object object)
返回与给定实体相关联的会话的标识符值。8
Query createFilter(Object collection, String queryString)
为给定的集合和过滤字符创建查询的新实例。9
Query createQuery(String queryString)
为给定的 HQL 查询字符创建查询的新实例。10
SQLQuery createSQLQuery(String queryString)
为给定的 SQL 查询字符串创建 SQLQuery 的新实例。11
void delete(Object object)
从数据存储中删除持久化实例。12
void delete(String entityName, Object object)
从数据存储中删除持久化实例。13
Session get(String entityName, Serializable id)
返回给定命名的且带有给定标识符或 null 的持久化实例(若无该种持久化实例)。14
SessionFactory getSessionFactory()
获取创建该会话的 session 工厂。15
void refresh(Object object)
从基本数据库中重新读取给定实例的状态。16
Transaction getTransaction()
获取与该 session 关联的事务实例。17
boolean isConnected()
检查当前 session 是否连接。18
boolean isDirty()
该 session 中是否包含必须与数据库同步的变化?19
boolean isOpen()
检查该 session 是否仍处于开启状态。20
Serializable save(Object object)
先分配一个生成的标识,以保持给定的瞬时状态实例。21
void saveOrUpdate(Object object)
保存(对象)或更新(对象)给定的实例。22
void update(Object object)
更新带有标识符且是给定的处于脱管状态的实例的持久化实例。23
void update(String entityName, Object object)
更新带有标识符且是给定的处于脱管状态的实例的持久化实例。Hibernate主键生成策略
实体对象的四种状态
Hibernate操作的对象有四种状态:
1、瞬时状态(Transient)/临时。2.、持久化状态(persistent)。3、托管状态(detached)/游离状态
1、当一个对象通过new 新创建的时候就是瞬时状态
瞬时状态下对象的主键没有值,也没有纳入session的管理,数据库表中也没有对应的记录,当我们调用save等相关的其他方法是则进入了持久化状态,
2、持久化状态下对象纳入了session管理中,对象标示符有值。Hibernate保证在同一个session实例的缓存中数据库中的一条记录只对应唯一的一个持久化对象。session在清理缓存时会根据持久化对象的属性变化会同步更新数据库。当session关闭后持久化状态就会变成托管状态。当持久化对象调用delete方法就由持久化变成了移除状态
3、托管状态下的特点:对象不处于session的管理中。但他曾经与某个持久化上下文发生过关联(session),对象标示符有值,数据库可能存在与之相对的记录。Hibernate不能够保证托管状态下的数据和数据库中的数据同步更新。
4、临时和游离状态下的对象特点:等待垃圾回收,
Hibernate 对象间的关联关系
多对一关联映射
一对多关联映射
如何对集合进行排序:
- 在HQL 语句中排序
- 在set 元素中排序
<set name="" inverse="true" order-by="排序列 排序方式"
<ket column="" />
<one-tomany class=""/>
</set>
<bag name="">
<ket column="" />
<one-tomany class=""/>
</bag>
多对多关联映射
一对一关联映射
Open Session In View模式
级联(cascade),反转(inverse),延迟加载,检索策略,和set元素介绍
1、级联
常用的cascade属性取值
cascade属性值
描述
none
当Session操作当前对象时,忽略其他关联的对象,它是cascade属性的默认值
save-update
当通过Session的save(),update(),及saveOrUpdate()方法来保存或更新当前对象时,级联保存所有关联的新建的瞬时状态的对象,并且级联更新所有关联的游离状态的对象
delete
当通过Session的delete()方法删除当前对象时,会级联删除所有关联的对象
all
包含save-update,delete的行为
2、控制反转
inverses属性指定了关联关系中的方向
inverse 设置为false,则为主动房,由主动方负责维护关联关系,默认是false。
inverse 设置为true,不负责维护关联关系。
建议:
1. 一般在一对多的时候在一的一方设置inverse 设置为true有助于性能提升。
1. 在简历两个对象的双向关联时,应该同时修改两个关联对象的相关属性。
2.建议inverse设置为true
- 延迟加载:延迟加载(lazy load 懒加载)是当真正需要数据时,才执行SQL语句进行查询。避免了无谓的开销。
3、检索策略
检索策略
运行机制
立即检索
立即加载与当前对象关联的对象,需要执行多条select语句
延迟检索
不立即加载与当前对象关联的对象,在第一次访问关联对象时才加载其信息
迫切左外连接检索
通过左外连接加载与当前对象的关联对象。为立即检索策略,但执行的select语句少,只执行1条select连接查询语句
属性
类级别
一对多关联级别
多对一关联级别
lazy
1.<class>元素中lazy属性的可选值为:true(延迟检索)和false(立即检索)
2. <class>元素中lazy属性的默认值为true
1.<set>元素中lazy属性的可选值为:true(延迟检索)、false(立即检索)和extra(增强延迟检索)
2. <set>元素中lazy属性的默认值为true
1.<many-to-one>元素中的lazy属性的可选 值为:proxy(延迟检索)、no-proxy(无代理延迟检索)和false(立即检索)
2.<many-to-one>元素中的lazy属性的默认值为true
fetch
没有此属性
1.<set>元素中fetch属性的可选值为:select(查询语句)、subselect(子查询语句)和join(迫切左外连接检索)
2. <set>元素的fetch属性的默认值为select
1.<many-to-one>元素中fetch属性的可选 值为:select(查询语句)和join(迫切左外连接检索)
2.<many-to-one>元素的fetch属性的默认值为select
1、检索方法
a) 通过Session类的get和load方法加载指定的OID的对象
b) 通过HQL,QBC等检索方法记载满足条件的对象
2、检索的作用域
a) 类级别:作用于当前对象。对当前对象时立即检索,还是延迟检索。默认延迟检索只对load有效
b) 关联级别:对关联对象是立即检索,延迟检索还是迫切左外连接检索。默认延迟检索。对所有检索方法有效
3、fetch的作用和取值
a) select 加载关联对象时通过select语句实现。默认值
b) subselect 加载关联对象时通过带子查询语句实现。
c) join 执行立即检索,采用迫切左外连接检索所有关联对象,lazy属性将被忽略。
总结:① select 和 subselect 适用于立即检索和延迟检索,join 仅使用立即检索。
② select 和 subselect 决定加载关联对象时查询语句形式,join决定加载关联对象的时机。
HQL查询
HQL介绍
HQL使用
一、实体查询(查询持久化类的全部信息)
Query 的list,iterate,uniqueresult方法 区别
List,查询一次,返回满足条件的全部信息的所有字段
Iterate方法,从数据库中检索出所有符合条件的所有记录,仅包含ID字段。
如果缓存中包含全部数据,无需再查询数据库直接应用(1+0)
如果缓存中不包含任何数据,需在查询数据库n次,依次查询各条记录(1+n)
大多数情况下进行list查询,当对象包含大量属性,或者需要加载大部分数据已经存在缓存中,可以使用iterate()
条件查询
聚合函数
参数绑定
- 占位符"?"
- 命名查询
- 封装参数(投影查询)
聚合函数
count(),sum(),max(),min(),avg()
模糊查询
分组,筛选
分页
子查询
连接查询
连接类型
HQL语法
左外连接
left outer join 或者 left join
迫切左外连接
left outer join 或者 left join fetch
内连接
inner join 或者 join
迫切内连接
inner join fetch 或者 join fetch
右外连接
right out jonin 或者 right join
命名查询
Criteria 查询
Hibernate调用本地SQL语句
Hibernate优化
1、避免or操作
where 子句包含or 操作,执行时不使用索引
可以使用in条件来替换
2、避免使用not
where 子句包含not 关键字,执行时该字段的索引失效
使用比较运算符替换not
3、避免like的特殊形式
查询时,尽可能少使用like
4、避免having子句
尽可能在where 子句中指定条件
5、避免使用distinct
在不要求或允许冗余时,应避免使用distinct
Hibernate 注解
Struts2 与 Hibernate 的集成
以上是关于Hibernate 学习教程的主要内容,如果未能解决你的问题,请参考以下文章
框架学习 Hibernate框架学习 Hibernate概念和api使用
[原创]java WEB学习笔记77:Hibernate学习之路---Hibernate 版本 helloword,