1、这个文件是我自己照着网上找到的马士兵老师的 hibernate 笔记截图版 手打出来的 有颜色部分的文字是我学习的时候自己添加的笔记说明(红色的除外) 刨除去颜色部分 就是和马士兵老师的原版文档一模一样了 希望能给好学的朋友一点帮助 目录 课程内容 5 1 HelloWorld5 2 Hibernate 原理模拟 - 什么是 O/R Mapping 以及为什么要有 O/R Mapping5 3 常见的 0/R 框架(了解) 5 4 hibernate 基础配置(重点) .5 5 ID 生成策略(重点 AUTO) 5 6 Hibernate 核心开发接口介绍(重点) 5 7 对象的三种状态(了解
2、) .5 8 关系映射(重点) .5 9 Hibernate 査询( HQL).5 10 在 Struts 基础上继续完善 BBS200 .5 11 性能优化(重点) .5 12 补充话题 .5 风格 5 1 先脉络,后细节 .5 2 先操作,后原理 .5 3 重 Annotation,轻 xml 配置文件 .5 资源 5 1 http:/www. hibernate.org .5 2 hibernate zh_CN 文档 .5 3 hibernate annotation references.5 环境准备 5 1 下载 hibernate-distribution-3.3.2.GA-dis
3、t 5 2 下载 hibernate-annotations-31.4.0.GA 5 3 注意阅读 hibernate compatibility matrix(hibernate 网站 download)5 4 下载 slf4jl.5.86 Hibernate HelloWorld .6 1 建立新 java 项目,名为 hibernate_0100_HelloWorld 6 2 学习建 User-library-hibernate,并加入相应的 jar 包 .6 3 引入 mysql 的 JDBC 驱动包 .6 4 在 mysql 中建立对应的数据库以及表 .6 5 建立 hibernat
4、e 配置文件 hibernate.cfg.xml.6 6 建立 Student 类 .6 7 建立 Student 映射文件 Student.hbm.xml 6 8 将映射文件加入到 hibernate.cfg.xml 中 .6 9 写测试类 Main,在 Main 中对 Student 对象进行直接的存储测试 6 10 FAQ: .6 11 Note: 6 12 建立能力 .7 建立 Annotation 版本的 HelloWorld .7 1 创建 teacher 表,create table teacher (id int primary key, name varhcar(20), t
5、itle varchar(lO);.7 2 创建 Teacher 类 7 3 在 hibernate lib 中加入 annotation 的 jar 包 7 4 参考 Annotaion 文档建立对应的注解 7 5 在 hibernate.cfg.xml 中建立映射 EJBQL(JPQL 1.0) QBC(Query By Criteria) QBE(Query By Example)“26 2 总结:QL 应该和导航关系结合,共同为査询提供服务。 .26 性能优化 26 1 注意 session.clear()的运用,尤其在不断分页循环的时候 .26 2 1+N 问题 ( 典型的面试题)
6、( 详见 hibernate_2800_Hibernate_1+N 项目) 26 3 list 和 iterate 不同之处(/主要为了面试 详见 hibernate_2900_Hibernate_list_iterate) 26 4 一级缓存和二级缓存和査询缓存(面试题)(详见 hibernate_3000_Hibernate_3KindsOf_Cache).26 5 事务并发处理(面试的意义更大 ) 27 课程内容 1 HelloWorld a) Xml b) annotation 2 Hibernate 原理模拟 - 什么是 O/R Mapping 以及为什么要有 O/R Mapping
7、 3 常见的 0/R 框架(了解) 4 hibernate 基础配置(重点) 5 ID 生成策略(重点 AUTO) 6 Hibernate 核心开发接口介绍(重点) 7 对象的三种状态(了解) 8 关系映射(重点) 9 Hibernate 査询(HQL) 10 在 Struts 基础上继续完善 BBS200 11 性能优化(重点) 12 补充话题 风格 1 先脉络,后细节 2 先操作,后原理 3 重 Annotation,轻 xml 配置文件 a) JPA b) hibernate extension 资源 1 http:/www. hibernate.org 2 hibernate zh_C
8、N 文档 3 hibernate annotation references 环境准备 1 下载 hibernate-distribution-3.3.2.GA-dist 2 下载 hibernate-annotations-31.4.0.GA 3 注意阅读 hibernate compatibility matrix(hibernate 网站 download) 4 下载 slf4jl.5.8 Hibernate HelloWorld 1 建立新 java 项目,名为 hibernate_0100_HelloWorld 2 学习建 User-library-hibernate,并加入相应的
9、jar 包 a) 项目右键-buildpath-configure build path-add library b) 选择 User-library,在其中新建 libraray,命名为 hibernate c) 在该 library 中加入 hibernate 所需 jar 包 i. hibernate core ii. /required iii. slf-nop jar 3 引入 mysql 的 JDBC 驱动包 4 在 mysql 中建立对应的数据库以及表 a) create database hibernate; b) use hibernate; c) create table
10、Student (id int primary key, namevarchar(20), age int); 5 建立 hibernate 配置文件 hibernate.cfg.xml a) 从参考文档中 copy b) 修改对应的数据库连接 c) 注释掉暂时用不上的内容 6 建立 Student 类 7 建立 Student 映射文件 Student.hbm.xml a) 参考文档 8 将映射文件加入到 hibernate.cfg.xml 中 a) 参考文档 9 写测试类 Main,在 Main 中对 Student 对象进行直接的存储测试 a) 参考文挡 10 FAQ: a) 要调用 n
11、ew Configuration().configure().buildSessionFactory(),而不是 要省略 configure,否则会出 hibernate dialect must be set 的异常 11 Note: a) 请务必建立自己动手査文挡的能力 b) 重要的是: i. 要建立自己动手查一手文档的信心 ii. 还有建立自己动手查一手文档的习惯! iii. 主动学习,砍弃被动接受灌输的习惯! 12 建立能力 a) 错误读完整 b) 读昔误的关键行 c) 排除法 d) 比较法 e) google 建立 Annotation 版本的 HelloWorld 1 创建 tea
12、cher 表,create table teacher (id int primary key, name varhcar(20), title varchar(lO); 2 创建 Teacher 类 3 在 hibernate lib 中加入 annotation 的 jar 包 a) hibernate annotaion jar b) ejb3 persistence jar c) hibernate common-annotations.jar d) 注意文裆中没有提到 hibernate-common-annotations.jar 文件 4 参考 Annotaion 文档建立对应的
13、注解 5 在 hibernate.cfg.xml 中建立映射HQL. EJBQL(JPQL 1.0) QBC(Query By Criteria) QBE(Query By Example)“ 2 总结:QL 应该和导航关系结合,共同为査询提供服务。 性能优化 1 注意 session.clear()的运用,尤其在不断分页循环的时候 a) 在一个大集合中进行遍历,遍历 msg,取出其中的含有敏感字样的对象 b) 另外一种形式的内存泄露 ( /面试题:Java 有内存泄漏吗?语法级别没有 但是可由 java 引起,例 如:连接池不关闭,或 io 读取后不关闭) 2 1+N 问题 (典型的面试题)
14、 (详见 hibernate_2800_Hibernate_1+N 项目) a) ManyToOne(fetch=FetchType.LAZY) /fetch=FetchType.LAZY 解决N+1问题 说明如下: /当多对一(ManyToOne)已经设定属性“ fetch=FetchType.LAZY “时 /只有当需要时(如:t.getCategory().getName()时) 才会去获取关联表中数据 可以解决N+1问题 b) BatchSize /BatchSize 解决N+1问题 说明如下: /在与查询表(此例中为Topic 类)关联的表类(此例中为 Category类)头处加Ba
15、tchSize(size=5) /表示每次可查出5条记录 从而减少了select语句的个数 c) join fetch /join fetch 解决N+1问题 说明如下: /修改hql语句为-“ from Topic t left join fetch t.category c “ d) QBC /QBC(Query By Criteria) 解决N+1问题 说明如下: /使用QBC 的 createCriteria(*.class)执行查询 也可避免N+1问题 3 list 和 iterate 不同之处( /主要为了面试 详见 hibernate_2900_Hibernate_list_it
16、erate) a) list 取所有 b) iterate 先取 ID,等用到的时候再根据 ID 来取对象 c) session 中 list 第二次发出,仍会到数据库査询 d) iterate 第二次,首先找 session 级缓存 4 一级缓存和二级缓存和査询缓存(面试题)(详见 hibernate_3000_Hibernate_3KindsOf_Cache) a) 什么是缓存 b) 什么是一级缓存,session 级别的缓存 c) I 什么是二级缓存,SessionFactory 级别的缓存,可以跨越 session 存在 i. 经常被访间 ii. 改动不大不会经常改动 iii. 数重有
17、限 d) 打开二级缓存 i. hibernate.cfg.xml 设定: true org.hibernate.cache.EhCacheProvider ii. Cache 注解( 由 hibernate 扩展提供) Cache(usage=CacheConcurrencyStrategy.READ_WRITE) 注:使用 EhCache 二级缓存 需要导入 ehcache-1.2.3.jar 及 commons-logging-1.0.4.jar 包 e) load 默认使用二级缓存,iterate 默认使用二级缓存 f) list 默认往二级缓存加数据,但是查询的时候不使用 g) 如果要
18、 query 用二级缓存,需打开查询缓存 true 调用 Query 的 setCachable (true)方法指明使用二级缓存 例如:session.createQuery(“from Category“).setCacheable(true).list(); h) 缓存算法:(纯为了面试) i. LRU LFU FIFO 1. Least Recently Used 最近很少被使用 2. Least Frequently Used (命中率高低) 3. First In First Out 按顺序替换 ii. memoryStoreEvictionPolicy = “LRU“ (ehca
19、che.xml 中配置) 5 事务并发处理(面试的意义更大) a) 事务:ACID i. Atomic Consistency Itegrity Durability b) 事务并发时可能出现的问题: 第一类丢失更新(Lost Update) 时间 取款事务 A 存款事务 B T1 开始事务 T2 开始事务 T3 查询账户余额为 1000 元 T4 查询账户余额为 1000 元 T5 汇入 100 元把余额改为 1100 元 T6 提交事务 T7 取出 100 元把余额改为 900 元 T8 撤销事务 T9 余额恢复为 1000 元(丢失更新) dirty read 脏读(读到了另一个事务在处
20、理中还未提交的数据) 时间 取款事务 A 存款事务 B T1 开始事务 T2 开始事务 T3 查询账户余额为 1000 元 T4 汇入 100 元把余额改为 1100 元 T5 查询账户余额为 1100 元(读取脏 数据) T6 回滚 T7 取款 1100 T8 提交事务失败 non-repeatable read 不可重复读 时间 取款事务 A 存款事务 B T1 开始事务 T2 开始事务 T3 查询账户余额为 1000 元 T5 汇入 100 元把余额改为 1100 元 T5 提交事务 T6 查询帐户余额为 1100 元 T8 提交事务 second lost update problem
21、 第二类丢失更新(不可重复读的特殊情况) 时间 取款事务 A 存款事务 B T1 开始事务 T2 开始事务 T3 查询账户余额为 1000 元 T4 查询账户余额为 1000 元 T5 取出 100 元把余额改为 900 元 T6 提交事务 T7 汇入 100 元 T8 提交事务 T9 把余额改为 1100 元(丢失更新) phantom read 幻读 时间 查询学生事务 A 插入新学生事务 B T1 开始事务 T2 开始事务 T3 查询学生为 10 人 T4 插入 1 个学生 T5 查询学生为 11 人 T6 提交事务 T7 提交事务 c) 数据库的事务隔离机制 i. 查看 java.sq
22、l.Connection 文档 ii. 1:read -uncommitted 2:read- committed 4:repeatable read 8:serializable (数字代表对应值) 为什么取值要使用 1 2 4 8 而不是 1 2 3 4 1=0000 2=0010 4=0100 8=1000(位移计算效率高) 1. 只要数据库支持事务,就不可能出现第一类丢失更新 2. read-uncommitted(允许读取未提交的数据) 会出现 dirty read, phantom-read, non-repeatable read 问题 3. read-commited(读取已提
23、交的数据 项目中一般都使用这个)不会出现 dirty read,因为只有另 一个事务提交才会读出来结果,但仍然会出现 non-repeatable read 和 phantom-read 使用 read-commited 机制可用悲观锁 乐观锁来解决 non-repeatable read 和 phantom-read 问 题 4. repeatable read(事务执行中其他事务无法执行修改或插入操作 较安全) 5. serializable 解决一切问题( 顺序执行事务 不并发,实际中很少用) d) 设定 hibernate 的事务隔离级别(使用 hibernate.connection
24、.isolation 配置 取值 1、2、4、8) i. hibernate.connection.isolation = 2(如果不设 默认依赖数据库本身的级别) ii. 用悲观锁解决 repeatable read 的问题(依赖于数据库的锁) (详见项目 hibernate_3100_Hibernate_Concurrency_Pessimistic_Lock) 1. select . for update 2. 使用另一种 load 方法-load(xx.class , i , LockMode.Upgrade) a) LockMode.None 无锁的机制,Transaction 结束
25、时,切换到此模式 b) LockMode.read 在査询的时候 hibernate 会自动获取锁 c) LockMode.write insert update hibernate 会自动获取锁 d) 以上 3 种锁的模式,是 hibernate 内部使用的(不需要设) e) LockMode.UPGRADE_NOWAIT 是 ORACLE 支持的锁的方式 e) Hibernate(JPA)乐观锁定(ReadCommitted) (详见项目 hibernate_3200_Hibernate_Concurrency_Optimistic_Lock) 实体类中增加 version 属性(数据库也
26、会对应生成该字段 ,初始值为 0),并在其 get 方法前加 Version 注解,则在操作过程中没更新一次该行数据则 version 值加 1,即可在事务提交前判断 该数据是否被其他事务修改过. Version 时间 转账事务 A 取款事务 B T1 开始事务 T2 开始事务 T3 查询学生为 10 人 查询账户余额为 1000 version=0 T4 查询账户余额为 1000 version=0 T5 取出 100 把余额改为 900 version=1 T6 提交事务 T7 汇入 100 元 T8 提交事务 ? version0 throw Exception T9 把余额改为 1100 元(丢失更新)