19
多对一与一对多 19
1 多对一单向关联 19
2 一对多单向关联 20
3 一对多(多对一)双向关联 20
多对多 21
1 单向关联:
21
2 双向关联:
22
关联关系中的CRUD_Cascade_Fetch 22
1 hibernate_1700_one2many_many2one_bi_crud 22
2 设定cascade以设定在持久化时对于关联对象的操作(CUD,R归Fetch管) 22
3 cascade仅仅是帮我们省了编程的麻烦而已,不要把它的作用看的太大 22
4 铁律:
双向关系在程序中要设定双向关联 23
5 铁律:
双向mappedBy 23
6 fetch 23
7 Update时@ManyToOne()中的cascade参数关系 23
8 Delete时@ManyToOne()中的cascade关系 23
9 O/RMapping 编程模型 24
10 要想删除或者更新先做load,除了精确知道ID之外 24
11 如果想消除关联关系,先设定关系为null.再删除对应记录,如果不删记录,该记录变成垃圾数据 24
12 练习:
多对多的CRUD 24
关系映射总结 25
1 什么样的关系,设计什么样的表,进行什么样的映射 25
2 CRUD,按照自然的理解即可(动手测试) 25
集合映射(不太重要) 25
1 项目名称:
hibernate_1800_Collections_Mapping 25
2 Set 25
3 List (与Set差不多 多个@OrderBy) 25
4 Map 25
继承映射(不太重要) 25
1 三种方式 25
作业:
25
1 学生课程、分数的设计(重要) 25
2 设计:
26
3 树状结构的设计(至关重要) 26
Hibernate 查询(Query Language) 27
HQL vs EJBQL 27
1 NativeSQL >HQL.> EJBQL(JPQL 1.0) > QBC(Query By Criteria) > QBE(Query By Example)" 27
2 总结:
QL应该和导航关系结合,共同为査询提供服务。
27
性能优化 27
1 注意session.clear()的运用,尤其在不断分页循环的时候 27
2 1+N问题 (典型的面试题) (详见hibernate_2800_Hibernate_1+N项目) 27
3 list和iterate不同之处(//主要为了面试 详见hibernate_2900_Hibernate_list_iterate) 27
4 一级缓存和二级缓存和査询缓存(面试题)(详见hibernate_3000_Hibernate_3KindsOf_Cache) 27
5 事务并发处理(面试的意义更大) 28
1 HelloWorld
a) Xml
b) annotation
2 Hibernate原理模拟 - 什么是O/R Mapping以及为什么要有O/R Mapping
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_CN文档
3 hibernate annotation references
环境准备
1 下载hibernate-distribution-3.3.2.GA-dist
2 下载hibernate-annotations-3[1].4.0.GA
3 注意阅读hibernate compatibility matrix(hibernate 网站download)
4 下载slf4jl.5.8
Hibernate HelloWorld
1 建立新java 项目,名为hibernate_0100_HelloWorld
2 学习建User-library-hibernate,并加入相应的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 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) 要调用 new 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 创建teacher 表,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文档建立对应的注解
5 在hibernate.cfg.xml中建立映射.../〉
6 参考文裆进行测试(注意文裆中缺少configure()的小bug)
7 FAQ:
@不给提示
a) 配置eclipse属性信息content assist-activation--加上@
What is and Why 0/R Mapping
1 JDBC操作数据库很繁琐
2 Sql语句编写并不是面向对象的
3 可以在对象和关系表之间建立关联来简化编程
4 0/R Mapping 简化编程
5 0/R Mapping跨越数据库平台
6 Hibernate_0200_OR_Mapping_Simulation
0/R Mapping Frameworks
1 hibernate
2 toplink
3 jdo
4 JPA
a) 意愿统一天下
Hibernate基础配置
1 对应项目:
Hibernate_0300_BasicConfiguration
2 介绍MSQL的图形化客户端
3 hibernate.cfg.xml:
hbni2ddl.auto:
create、update。
。
。
。
a) 先建表还是先建实体类—先建表
4 搭建日志环境并配置显示DDL语句
a) slf4j与log4j的关系:
slf4j像是一个大管家,可以管理许多的日志框架,log4j是其中之一
b) 加入slf4j-log4j.jar,加入 log4j 的 jar 包,去掉 slf4-nop.jar
c) 从hibernate/project/etc 目录 copy log4j.properties
d) 査询hibernate文裆,日志部分,调整日志的输出策略
5 搭建jUnit环境
a) 需要注意jUnit的Bug
6 hibernate.cfg.xml:
show_sql 是否输出SQL语句
7 hibernate.cfg.xml:
format_sql 格式化SQL语句,美化SQL语句
-- 格式化显示输出sql -->
true
8 表名和类名不同,对表名进行配置
a) Annotation:
@Table
b) xml:
自己査询
9 字段名和属性相同
a) 不用写@column 与默认的@Basic效果一样
b) Xml中不用写 column
10 字段名和属性名不同
a) Annotation:
@Column
b) xml:
自己査询
11 不需要psersistence的字段(不用列)
a) Annotation:
@Transient 定义不写入数据库,属性透明
b) xml不写
12 映射日期与时间类型,指定时间精度
a) Annotation:
@Temporal(参数) 参数有3种 只显示时间,只显示日期,时间日期都显示
//@Temporal(TemporalType.DATE) 只显示日期
//@Temporal(TemporalType.TIME) 只显示时间
//@Temporal(TemporalType.TIMESTAMP) 显示日期与时间
b) xml:
指定 type
13 映射枚举类型( 比较少用)
a) @Enumerated
@Enumerated(EnumType.ORDINAL) 枚举类型按位置数,如:
0,1,2 ...存储
@Enumerated(EnumType.STRING) 枚举类型按设定值存储
b) xml:
麻烦
14 字段映射的位置(field或者get方法)
a) best practice:
保持 field(变量定义) 和 get set 方法的一致
15 @Lob
16 课外:
CLOBBLOB类型的数据存取
17 课外:
Hibernate自定义数据类型
18 hibernate 类型
ID生成策略
1 对应项目:
hibernate_0400_ID
2 注意:
a) 我们观察hibernate生成表的结构并不是为了将来就用它生成,(可能还有自己的扩展,比如index等)而是为了明白我们应该建立什么样的表和实体类映射
3 xml生成id
a) generator
b) 常用四个:
native identity sequence uuid
4 注解方式:
@GeneratedValue
a) 自定义ID
b) AUTO(直接写 @GeneratedValue 相当如native) (@GeneratedValue(strategy=GenerationType.AUTO))
i. 默认:
对 MySQL,使用auto_increment
ii. 对 Oracle使用hibernate_sequence(名称固定)
c) IDENTITY(@GeneratedValue(strategy=GenerationType.IDENTITY))
d) SEQUENCE(@GeneratedValue(strategy=GenerationType.SEQUENCE))
i. @SequenceGenerator(可自定义在数据库生成指定的sequence名)
@Id
//在@GeneratedValue中增加 generator="teacherSEQ"
@GeneratedValue(strategy=GenerationType.SEQUENCE,generator="teacherSEQ")
//"teacherSEQ"为@SequenceGenerator的标识名
//"teacherSEQ_DB"为指定到数据库生成的Sequence名
@SequenceGenerator(name="teacherSEQ", sequenceName="teacherSEQ_DB")
public int getId() {
return id;
}
e) TABLE (可以忘记)
i. @TableGenerator
@TableGenerator(
name="teacherID", //被调用的TABLE名字
table="teacherID_DB", //数据库建立的表名
pkColumnName="key_value",
pkColumnValue="pk_value",
valueColumnName="teacher", //pkColumnValue对应类名
allocationSize=1 //pkColumnValue对应类名
)
@GeneratedValue(strategy=GenerationType.TABLE,generator=" teacherID ")
注:
如果使用注解方式的uuid 如下:
@Id
@GeneratedValue(generator="teacherUUID")
@GenericGenerator(name="teacherUUID", strategy="uuid")
5 FAQ;
a) 用Junit测试时Hibernate Session Factory初始化异常不提示.疑似一个bug
b) 用main来做测试
6 联合主键
a) Xml方式:
composite-id
i. 将联合主键的属性提取出来,重新编写一个pojo类(原pojo类中的id,name要删除 并新加入属性“StudentPK”)
public class StudentPK implements Serializable {
private String id;
private String name;
… …
ii. 新建pojo类必须实现 java.io.Serializable 序列化接口
iii. 新pojo类要重写equals和hashCode方法
@Override
public boolean equals(Object o) {
if(o instanceof StudentPk) {
StudentPk pk = (StudentPk)o;
if(this.id == pk.getId() && this.name.equals(pk.getName())) {
return true;
}
}
return false;
}
@Override
public int hashCode() {
return this.name.hashCode();
}
iv. 联合主键生成策略XML配置方法