学习hibernate上册

Hibernate

引入问题:开发的语言是面向对象的,但是在面向数据库操作层面还是面向关系的,因此我们需要手工来做转换工作。

  1. 什么是ORM(Object Relation Mapping)

Object:对象,java对象,此处特指JavaBean
Relational:关系,二维表,数据库中的表。
映射|映射元数据:对象中属性,与表的字段,存在对应关系。

  1. 关于hibernate

纯面向对象来跟数据库交互
1.Hibernate是重量级JavaEE应用的持久层解决方案,是一个关系数据库ORM框架
a)ORM 就是通过将Java对象映射到数据库表,通过操作Java对象,就可以完成对数据表的操作
2.Hibernate提供了对关系型数据库增删改成操作

  1. 开发步骤

1.创建数据库和表
2.创建对应的实体类
3.导入Hibernate的jar包
4.编写核心配置文件hibernate.cfg.xml
5.编写映射文件*.hbm.xml(和VO放到一起)
使用Hibernate API进行开发

  1. 关于Jar包难用的问题
    eclipse中提供了User Libraries 进行:

打开Eclipse,点击工具栏中的window->Preferences,选择左侧中的java->User Libraries,使用的话配置build path->add libraries
第二种就是使用maven项目进行配置。关于eclipse, F1的帮助文档问题需要仔细翻阅, 关于myeclipse比eclipse更为好用
提这点的目的是在于, 想成为优秀程序员之一条件就是提高效率, 用最短的时间做最多的事(学习新的 技术, 知识, 压缩以前做的项目的时间)

5.关于配置信息
关于配置信息主要还是查官网, 官网手册上面写的就是属性可以根据etc文档进行复制, 避免时间的浪费
Alt text

6.数据库4种语言
DDL(Data Definition Language)数据库定义语言
DML(Data Manipulation Language)数据操纵语言
DCL(Data Control Language)数据库控制语言
TCL(Transaction Control Language)事务控制语言

  1. 映射文件概图
    Alt text

8.使用API进行编程
Alt text
Alt text
Alt text

  1. 对象的三种状态

Alt text

Hibernate规定对象具备三种状态,瞬时状态,持久状态,托管状态
瞬时状态:transient,session没有缓存对象,数据库也没有对应记录
持久状态:persistent,session有缓存对象,数据库有对应的记录
托管状态:detached,session没有缓存对象,数据库也有记录

  1. 主键生成策略

1.increment:由Hibernate以递增的方式生成
2.identity:由底层数据库的自增主键生成机制产生,要求底层数据库支持自增字段类型,如MySQL的auto_increment和SQL Server的identity
3.sequence:由底层数据库的序列生成机制产生,比如Oracle的序列
4.native:根据底层数据库对自动生成标识符的支持能力来智能选择

  1. session的两种创建方式
    getCurrentSession(),openSession()
    Alt text
    currentSession会先到一级缓存中查找

一级缓存又称为session级别的缓存,为优化程序性能,每次获取数据,Hibernate会优先从session缓存中获取,如果有就直接使用,如果没有,再查数据,并将其存储到缓存中。当session关闭,则一级缓存销毁。

  1. 一级缓存get&load
    get如果获取的是id则会在代理对象中进行查找,而不会直接发送sql语句

13.映射
多表关系
表和表之间存在的关系就是主外键关系,而对象和对象之间通常存在以下三种关系:
一对一,一对多,多对多
我们首先一起来看看表之间是怎么建立这三种关系的。
一对一:(一个人对应一个身份证号)
一对多:(一个客户对应多个订单)
多对多:(老师可以带多个班级,一个班可以被多个老师带)

  1. hibernate创建步骤为:
    1.创建具备一对多关系的表(两张表)
    2.创建对应的类,并建立联系(两个类)
    3.添加两个类的映射文件
    4.编写测试程序,测试增删改查的应用及特点
    5.分别建立单向和双向的映射关系观察实验结果

Alt text

15.控制反转

为什么要用inverse:结果就是节省了update语句,注意要设置Phone跟Person的关系,提升了性能。
所以一对多,一般就是把关系交给多的一方来维护

原因:关系由多的一方来维护,表现的就是在插入数据的时候直接建立联系
而不需要再逐个去发送更新语句

  1. 级联操作
    save-update
    级联操作主要作用是提高我们的开发效率,我们保存一的一方, 让级联自动去保存多的一方
    save-delete
    如果这个关系是由一的一方来维护,则会清除掉关联关系,再执行删除
    如果这个关系是由多的一方来维护,则会出现外键约束异常
    所以当我们将关系交给多的一方来维护时,可以设置级联删除

Alt text
17. 关于删除的时候的场景:
有时候,关系已经交给多的一方来维护,我们要删除的一的一方,但是不想删除多的一方数据,只是去除掉关系,比如一个员工离职了,那他跟其他部门的关系要清除,但是这些部门是不能删除的
这个时候就是不设置级联删除,只能手动进行解除关系,里面是因为级联的时候是通过set类型的属性进行删除, 只要清空set即可
Alt text

方法总览:

save-update:一的一方保存,同时保存多的一方
delete:删除一的一方,同时删除多的一方
delete-orphan:孤儿删除,解除一和多的关系,同时将多的一方删除
如果需要配置多项,使用逗号分隔。<set cascade="save-update,delete">
all : save-update 和 delete 整合
all-delete-orphan : 三个整合
18.多表建立关系(多对多)

核心配置文件:
Alt text
Alt text

api进行操作:
Alt text
Alt text

19.抓取策略

检索方式

  1. 立即检索:立即查询,在执行查询语句时,立即查询所有的数据。get
  1. 延迟检索:延迟查询,在执行查询语句之后,在需要时在查询。load

比如:
get:立即检索。get方法一执行,立即查询所有字段的数据。
load:延迟检索。默认情况,load方法执行后,如果只使用OID的值不进行查询,如果要使用其他属性值将查询。(会受到映射文件的配置影响)

检索级别

1.类级别检索:当前的类的属性获取是否需要延迟。
2.关联级别的检索:当前类 关联 另一个类是否需要延迟。

类的:
Alt text
关联级别的:
1.容器 提供两个属性:fetch、lazy

  • a)fetch:确定sql的语法,以什么样的格式抓取数据。
  • b)lazy:确定关联对象是否延迟。
    2.fetch:select、join、subselect
  • a)select:使用多个select语句(默认值)
  • b)join:底层使用迫切左外连接
  • c)subselect:使用子查询
    3.lazy:true、false、extra
  • a)true:延迟(默认值)
  • b)false:立即
  • extra:极其懒惰

1.lazy="true",延迟,先查询客户select,需要订单信息时,再查询订单select
2.lazy="false" , 立即加载,先查询客户select,立即查询订单select
3.lazy="extra",极其懒惰(延迟),先查询客户select, 如果需要查订单的时候将会优先用函数进行查询相关操作

  1. subselect会以子查询的方式来发送查询语句,而select是发送多条select语句
    而extra的情况下,两者的表现是一样的
  2. join,后面的lazy设置成什么,结果都一样
  3. 将产生多条select语句
20. 批量查询

1.当人员 关联查询 手机信息,给每一个客户生产一个select语句查询订单。批量查询使用in语句减少查询订单语句个数。
2.默认:select * from t_order where customer_id = ?
3.批量:select * from t_order where customer_id in (?,?,?,?)
4.hibernate中配置文件进行配置<set batch-size="5"> 5表示括号中?个数。


口述总结篇:

1.ORM对象关系映射

  • ORM组件有哪些
  •  a)jdbc
    
  • b)hibernate
  • c)MyBatis
  •  d)SpringData
    

2.hibernate环境搭建

  • 1)导入相关jar包
  • 2)配置文件(使用手册里面去找)
  •  a)hibernate.cfg.xml	 ,配置数据源,
    
  • 2)映射文件
    • 1)命名:实体类名.hbm.xml
    • 2)位置:和实体类放在一起
  • 3)工具类(使用手册里面去找)
  • 4)操作数据库的流程
  • a)获取sessionFactory
    
    • b)通过sessionFactory创建session
    • c)开启事务
    • d)操作数据库
    • e)提交事务

3.主键生成策略

  • native
  • identify
  • sealizetion

4.一级缓存(session级别缓存)

  • 1)get
  •  1)先打session缓存中去找,如果找到了就直接返回,没有再发送sql去查询
    
  •  2)缓存只对当前session有效
    

5.get&load

  • 1)get:
    a)调用完后立即查询
    b)查询一个不存在的数据,返回的是一个空
  • 2)load(懒加载)
    a)它返回的是一个代理对象,这个对象中id有值
    b)当调用非id属性的时候就会发送sql去查询
    c)查询一个不存在的数据直接抛出异常

6.一对多

  1. 配置文件
  • 一的一方
  1. vo:要保存多的一方的set
    2. 配置文件:

name:一的一方中保存多的一方的属性名称
"< key >":配置关联关系
< one-to-many>:配置多的一方的全类名

  • 多的一方
    1. vo:要有一的一方的对象
    2. 配置文件

a)< many-to-one>
name:多的一方中保存一的一方的属性名称
column:做为外键的一个列名称

  1. 添加
    1. 在一对多的情况下关联字段的维护权权限在一的一方
    2. 一般情况下维护全要给多的一方
  • a)invers=true
  • b)在多的一方建立关系
  1. 查询
    1. 查询一个客户的时候用到订单的时候才会去查询

  2. 删除
    1. 在删除一个有订单的客户要手动解除关系,但是存在垃圾数据

  3. 事务提交
    1. 提交事务
    2. 关闭session
    3. 当缓存中的数据发送变化的时候会把缓存中的数据刷到数据库

6.级联属性
1. save-update : 保存一的一方多的一方自动保存
2. delete: 删除一的一方同时如果有多的一方也有数据也删除
3. delete-orphan(孤儿删除): 删除和当前对象解除关系的对象
4. 常用的是all(save-update+delete)

1.多对多
>1. 建表开始: 注意组合主键
2. 实体类 :两边都要用set
3. 配置 :

teacher
< set>
1. name:储存另一方的集合名词
2. table:中间表的名称
3. < key>: name:外键名称
4. < many-to-many>
+ 1)calss:另一方的实体类名称
+ 2)column:另一方的外键名称

班级
1)和上面的相反

4.添加
1. 默认是两边都有中间表的维护权限,只要有一方维护就可以。(在维护全的那边建立关系)
2. 级联属性
a)维护权在那边级联属性就加在哪里
b)删除(慎重)

5.抓取策略
1. 类级别的抓取: get&load 懒加载机制,可以控制这种机制。加一个lazy=false
2. 关联级别的抓取(了解)

  a)fetch:决定以什么样的方式查询
		1)select
		2)join
		3)subseelct
	b)lazy:赖的程度
		1)true
		2)false
		3)extra--极其懒惰

6.HQL

  1. 面向对象的查询语言
    2. 在hibernate里面查询的
    3. 可以查询返回一个list

7.批量查询
1)每次查询N个客户的订单
2)在映射文件中的set标签里面加一个batch-size=n

8.HQL

 	1)面向对象的查询语句
2)只在HIbernate里面有效
3)提供的方法
	a)查询一个list
		2)query.list()
	b)查询个单个的对象
		1)query.uniqueResult()
	c)投影:展示部分字段
		1)如果展示一个字段的时候用字符串去接收
		2)如果展示多个字段的时候用Object数组去接收
		3)在HQL可以调用构造器
	d)排序
	e)分页
	f)分组
	g)绑定参数
		1)问号(?)
			a)从0开始的
		2):属性名称
	h)聚合函数
		1)不能用*(select count(*)from Customer)
		2)返回的结果集用uniqueResult()接收
			a)返回的是一个long类型
	i)连接查询
		1)笛卡尔积效率
			a)产生的原因是没有关联条件
		2)连接查询

9.命名查询

    1)HQL语句放到了映射文件
	2)局部命名查询
	a)定义:在class节点里面
	b)如何调用
		1)session.getNameQuery("namespace.class.queryName")
3)全局的命名查询
	a)定义:在class节点外面
	b)如何调用
		1)session.getNameQuery("queryName")
4)HQL语句里面不能出现*号
posted @ 2017-12-16 11:32  老螃蟹  阅读(137)  评论(0编辑  收藏  举报