一、执行流程
![](https://img.haomeiwen.com/i5654620/e450dcc900a5b893.png)
二、介绍Hibernate(扯皮)
1.Hibernate 是一个持久化框架
(1)从狭义的角度来讲,“持久化” 仅仅指把内存中的对象永久的保存到硬盘中的数据库中。
(2)从广义的角度来讲,“持久化” 包括和数据库相关的各种操作。如:CRUD。
2.Hibernate 是一个 ORM 框架
ORM:对象关系映射。O 面向对象:类、对象、属性。R 面向关系:表、行(记录)、列(字段)。M 映射。
ORM 思想:关系数据库中的 行(记录)映射一个对象,程序员可以把对数据库的操作转化为对对象的操作。
在 Hibernate 中,存在 对象关系映射文件用来描述对象与表记录之间的映射关系。
3.Hibernate 配置文件:hibernate.cfg.xml ,配置数据库连接、Hibernate 本身的一些信息、对象关系映射。
4.Entity.hbm.xml 配置文件:对象关系映射文件。
5.Session 接口:Session 是应用程序与数据库之间交互操作的一个单线程对象,是 Hibernate 运作的中心。Session 有一个一级缓存,相当于 JDBC 中的 Connection。
6.SessionFactory 接口:根据配置生成 Session 的工厂。
7.Transaction :事务,可以通过 Session 来开启事务。
三、单独整合Hibernate
(1)导包
![](https://img.haomeiwen.com/i5654620/ec2be763267d8a6d.png)
(2)编写hibernate.cfg.xml主配置文件
![](https://img.haomeiwen.com/i5654620/42b8ef27dcacf911.png)
这里把sessionFactory整合到Spring的配置文件中去了,所以在hibernate的配置文件中没有。
(3)编写实体及实体映射文件Entity.hbm.xml 、Entity.java
![](https://img.haomeiwen.com/i5654620/c60725799ccb2cf1.png)
![](https://img.haomeiwen.com/i5654620/000c7d065dfdf789.png)
四、Spring与Hibernate的整合
1.把sessionFactory配置到spring容器中
![](https://img.haomeiwen.com/i5654620/be038f025ea33277.png)
配置方案一(在实际项目中最常用)
![](https://img.haomeiwen.com/i5654620/58bdaa5d0a92f341.png)
![](https://img.haomeiwen.com/i5654620/3725ac3cfbcafb6e.png)
配置方案二
![](https://img.haomeiwen.com/i5654620/d90bef9df6ef7697.png)
2、spring整合c3p0
(1).配置db.properties
![](https://img.haomeiwen.com/i5654620/9225f2d51db8ad68.png)
(2)、配置c3p0连接池
![](https://img.haomeiwen.com/i5654620/bdc1dfdee5146ed4.png)
![](https://img.haomeiwen.com/i5654620/70303482127d705f.png)
(3)、DaoImpl继承HibernateDaoSupport
![](https://img.haomeiwen.com/i5654620/0a354ec33b15b22f.png)
hql:
![](https://img.haomeiwen.com/i5654620/cdc0a2db49755272.png)
criteria:
![](https://img.haomeiwen.com/i5654620/e4c0b326337474fa.png)
![](https://img.haomeiwen.com/i5654620/a280a975bc0962f9.png)
3、Spring整合aop事务
(1)、配置核心事务管理器
![](https://img.haomeiwen.com/i5654620/2782277f02ccacf8.png)
(2)xml配置
配置通知:
![](https://img.haomeiwen.com/i5654620/ca489b8ae122cfe3.png)
进行织入:
![](https://img.haomeiwen.com/i5654620/769e614181d9d761.png)
(3)注解配置
开启注解:
![](https://img.haomeiwen.com/i5654620/2b945b6b3bb67a43.png)
对业务方法进行事务注入:
![](https://img.haomeiwen.com/i5654620/6dfb2eeea5ba04d8.png)
![](https://img.haomeiwen.com/i5654620/fdbf553821b687ed.png)
五、struts与Hibernate的整合
1、导包
struts-spring-plugin.jar
2、配置常量
![](https://img.haomeiwen.com/i5654620/ee12bf24ff82e94e.png)
3、整合方案一:由struts2创建action,由spring来维护action的依赖属性
![](https://img.haomeiwen.com/i5654620/0e337d71db000fa8.png)
整合方案2:Spring负责创建action以及组装
![](https://img.haomeiwen.com/i5654620/f34839a88c719a4d.png)
![](https://img.haomeiwen.com/i5654620/97569a04940b4ea8.png)
六、单独的Hibernate详解
框架搭建
1、导包
导入lib下的required下的包
2、准备实体&映射文件
在实体所在包下新建映射文件(名称:类名.hbm.xml),导入dtd约束(在hibernate-mapping-3.0.dtd)
![](https://img.haomeiwen.com/i5654620/521219da898815f4.png)
![](https://img.haomeiwen.com/i5654620/8963d0f0ac49fccc.png)
3、准备主配置文件
在src目录下,新建hibernate.cfg.xml主配置文件,导入dtd约束(在hibernate-configuration-3.0.dtd)
![](https://img.haomeiwen.com/i5654620/f3ef431e8b038608.png)
![](https://img.haomeiwen.com/i5654620/482f4affab5c3e97.png)
4、书写代码
配置详解
package属性:填写一个包名,后续配置中默认类所在包即为package属性填写的包
映射表与类的对应
name属性:类名
table属性:表名
name属性:类中主键属性名
column属性:表中主键名,默认列名为属性名
length属性:当前列的长度,默认数据库对于类型最大长度
type属性:当前列的类型,默认自动检测属性
generator属性:主键生成策略
代理主键:
increment:先查询表中主键最大值,加1作为新的主键值.
identity:依赖于数据库的主键自增
sequence:使用数据库中的序列
hilo:hibernate自己用高低位算法完成主键自增
uuid:生成随机字符串作为主键(长度应大于32位)
native(常用):自动根据数据库 三选一.(identity|sequence|hilo)
自然主键:
assigned:hibernate不生成主键.由开发人员自己设置主键值.
name属性:类中主键属性名
column属性:表中主键名,默认列名为属性名
length属性:当前列的长度,默认数据库对于类型最大长度
type属性:当前列的类型,默认自动检测属性
主配置文件
整体结构在框架搭建的主配置文件中。
自动建表(hibernate.hbm2ddl.auto)
create:自动建表,每次启动hibernate都会自动建表,即使表已经存在,仍然会删除重新建。
create-drop:自动建表,每次启动hibernate都会自动建表,每次运行完成后会将表删除。
update:自动建表,如果有表,就不在重新创建,如果配置改变,自动更改表结构。
validate:不会自动创建表结构,只负责在启动时检验表结构,检出问题后会抛出异常。
API详解
![](https://img.haomeiwen.com/i5654620/8b0eefe15b1aa7f1.png)
根据配置信息创建session对象。
1. SessionFactory创建需要消耗较多的内存资源。
2. SessionFactory是线程安全的设计。
结论:在一个web项目中确保只有一个SessionFactory存在。
![](https://img.haomeiwen.com/i5654620/ceeef6d0a0d54648.png)
Session
hibernate中操作数据库的核心对象。
1. 操作增删改查
2. 获得事务操作对象
![](https://img.haomeiwen.com/i5654620/8b3731006c63d977.png)
Transaction
用于操作事务的对象
![](https://img.haomeiwen.com/i5654620/c9df71d0e3c2f759.png)
1、public的空参构造
2、准备属性,public的set/get方法
3、提供oid,映射主键字段
4、标识属性尽量使用基本数据类型的包装类
5、类不能被final修饰
对象的三种状态
瞬时 没id,没关联(session关联)
持久 有id,有关联(session关联)
游离 有id,没关联(session关联)
持久化状态:持久化状态对象会在事务提交时会持久化到数据库,我们需要将对象持久化到数据库,就需要把对象转换为持久化状态。
一级缓存
一级缓存:也称为session缓存.属于线程级别缓存. 该缓存本质其实就是一个集合.该集合被放置到了session对象中.所以也叫session缓存.因为session是线程级别的.所以该缓存属于线程级别缓存.
缓存的作用:提高查询、修改效率。
查询:
1. 根据id查询对象
2. ResultSet会被封装成对象,放入缓存以及返回程序。如果缓存中存在要查id的对象,返回缓存中的对象。
修改:
1. 根据id查询对象
2. ResultSet会被封装成对象,一式两份,分别放入session缓存以及缓存快照中
3. 事务在提交时,会比对session缓存中的以及快照中的对象是否发生变化。如果发生变化执行修改。
hibernate中的事务管理
![](https://img.haomeiwen.com/i5654620/7fd12e1300b62a8c.png)
1、事务在service层管理。
2、确保service层和dao层使用的时同一个Connection,调用getCurrentSession方法是从ThreadLocal中获得与线程绑定的session。
3、getCurrentSession必须配置才能使用
![](https://img.haomeiwen.com/i5654620/35dca7d54a199856.png)
4、getCurrentSession方法获得的session对象,会在事务提交时自动关闭,不用手动关闭。
一对多|多对一关系
ORM:对象关系映射
o:一的一方使用集合,多的一方直接引用一的属性
r:多的一方使用外键引用一的一方
m:一对多关系映射,多对一关系映射
![](https://img.haomeiwen.com/i5654620/576f7eda388d316f.png)
应用
Cascase属性:级联操作
(1)、none:默认值,不级联
(2)、save-update:级联保存或级联更新
(3)、delete:级联删除
(4)、all:save-update+delete
结论:Cascase属性的性质属于减少开发时书写代码量的配置,可以不用靠写代码代替,级联操作尤其级联删除配置使用风险大,不建议使用。
inverse属性:
- true:放弃
- false(默认):维护
一对多中可以使用Inverse属性放弃维护关系,多对一中不能放弃维护关系。
![](https://img.haomeiwen.com/i5654620/325c36c5537091d6.png)
结论:为了避免维护关系SQL打印冗余,可以在一的一方放弃维护。配置后注意,表达关系只能通过多的一方来维护。
多对多关系
ORM:对象关系映射
(1)、r:使用第三张表,该表至少两列,两列都是外键
(2)、o:两方都用集合来表达引用多个对方
(3)、m: 多对多映射文件
应用
Cascade属性:级联操作
与一对多|多对一关系中相同的操作
不推荐使用delete
inverse属性:
(1)、true:放弃
(2)、false(默认):维护
结论:为了避免维护关系重复造成异常抛出,根据业务需要由一方放弃维护。放弃的规则:谁不依赖,谁放弃。例如:订单和商品,商品不依赖订单的存在,商品放弃维护。
Hibernate中的查询
(1)根据OID查询
(2)对象属性导航
(3)HQL查询
(4)Criteria查询
(5)原生SQL查询
HQL
Hibernate Query Language:hibernate查询语言
该查询语言是面向对象的查询语言.
HQL语句中绝对不可能出现与数据库相关的信息.
该语言是Hibernate独有的语言.只能在Hibernate中使用
一. 基础语法
![](https://img.haomeiwen.com/i5654620/fad0454a632b34ea.png)
二. 投影查询
查询一个属性
![](https://img.haomeiwen.com/i5654620/eb4d35635668fbb0.png)
查询两个属性
![](https://img.haomeiwen.com/i5654620/cd3e5cc84cd6ba7f.png)
查询多个对象,并封装到对象中
![](https://img.haomeiwen.com/i5654620/e1cce441af89de1e.png)
三. 条件查询
问号占位符
![](https://img.haomeiwen.com/i5654620/835c93551a0f4803.png)
命名占位符
![](https://img.haomeiwen.com/i5654620/61f0af2645a719e2.png)
四. 分页查询
![](https://img.haomeiwen.com/i5654620/f20ebc4878c467d7.png)
五. 排序
desc降序,asc升序
![](https://img.haomeiwen.com/i5654620/774fe8ace9dc5a70.png)
六. 聚合函数查询
Count、Max、Min、Sum、Avg
![](https://img.haomeiwen.com/i5654620/b0c79c210b293eab.png)
七. 多表查询
内连接
![](https://img.haomeiwen.com/i5654620/874d47658b4993dc.png)
迫切内连接
![](https://img.haomeiwen.com/i5654620/bc75b690b439823d.png)
左外连接
![](https://img.haomeiwen.com/i5654620/198a3d1a6fa626a2.png)
左外迫切连接
![](https://img.haomeiwen.com/i5654620/3cbbb835e52e7d2e.png)
右外连接、右外迫切连接在左的基础上把left换为right即可。
结论:HQL适用于单表或简单多表,业务逻辑较为复杂的多表仍然需要使用原生SQL书写.
Criteria查询
hibernate框架中独有的查询方式.
Criteria是无语句面向对象查询.
Criteria一般用于单表查询.
一、基础查询
![](https://img.haomeiwen.com/i5654620/271350a217f60dea.png)
二、条件查询
![](https://img.haomeiwen.com/i5654620/c4023b99a3745267.png)
三、分页查询
![](https://img.haomeiwen.com/i5654620/a8f4ecfacade33f0.png)
四、排序查询
![](https://img.haomeiwen.com/i5654620/4e709d39d6cc300a.png)
五、聚合查询
![](https://img.haomeiwen.com/i5654620/8f96e8e9ef8194b7.png)
离线Criteria查询对象
离线Criteria:不需要session就可直接创建
![](https://img.haomeiwen.com/i5654620/d65e008846f90ca1.png)
结论:适合单表
原生SQL
一、基本查询
![](https://img.haomeiwen.com/i5654620/8ed6374f6dca1cd4.png)
将指定结果封装到对象中
![](https://img.haomeiwen.com/i5654620/8872f41706c8c662.png)
二、条件查询
参数查询:可以用问号|命名占位符
![](https://img.haomeiwen.com/i5654620/4f672399f19939e7.png)
三、分页查询
![](https://img.haomeiwen.com/i5654620/347f86d581e2a475.png)
用于复杂业务查询
查询策略
类级别查询策略
lazy属性:是否懒加载|延迟加载
true(默认值):懒加载|延迟加载
false:立即加载
![](https://img.haomeiwen.com/i5654620/739ccdbafedbc6ec.png)
原理:懒加载时,load方法不会立即查询,会返回要查询的对象的代理对象,这个代理对象对当前操作的session进行封装,在获得对象的属性时,能够根据关联的session加载数据。
注意事项:返回对象的初始化操作一定要在session关闭之前完成,否则会抛出no-session异常。
集合加载策略(一对多|多对多)
lazy属性:决定集合加载策略
true(默认值):懒加载|延迟加载
false:立即加载
extra:极其懒惰,在查询数量时,只查询数量,不查询内容。
fetch属性:指定集合的加载方式
select(默认值):加载集合时使用单表查询加载
join:加载集合时使用左外连接查询(使用改属性,lazy属性会失效)
subselect:使用子查询加载多个集合,如果只加载一个,效果和select相同。
![](https://img.haomeiwen.com/i5654620/6a95e21f8cfc0d0c.png)
属性加载策略(多对一)
lazy属性:决定属性加载策略
proxy(默认值):由对方类级别策略代我决定
false:立即加载
fetch属性:指定属性的加载方式
select(默认值):单表查询加载数据
join:使用多表查询同时加载数据(使用改属性,lazy属性会失效)
![](https://img.haomeiwen.com/i5654620/f85a5f7aff56e818.png)
查询策略结论:查询策略中涉及的所有属性都使用默认值
问题一:sql语句打印n+1问题
batch-size属性:一次加载几个客户的集合,默认值为1.使用该属性选择一次加载几个客户的集合来缓解n+1问题
![](https://img.haomeiwen.com/i5654620/75dd9820e466d2e1.png)
问题二:dao返回的代理对象,service中关闭了session。在web层使用代理对象时,session已经关闭。会抛出no-session异常。
解决方案:
1. 不使用getCurrentSession,自己将session与现程绑定。
2. 使用过滤器,由过滤器中后处理代码将session关闭。
上述操作,交由spring管理。
hibernate核心总结:
网友评论