A:hibernate持久化介绍与主键生成策略
a:持久化类
persistent object (po)
po=pojo+hbm映射配置
对应hibernate中的po编写规则
1:必须提供一个无参数public构造方法
2:所有属性要private,对外提供public的get/set方法
3:在po类中必须提供一个标识属性,让他与数据库中的主键对应,我们管这个属性交oid.
4:po类中的属性尽量使用基本数据类型的包装类
int-Integer double-Double float-Float
5:po类他可以使用final修饰符
oid作用
1:oid指的是与数据中的表的主键对应的属性
2:hibernate 框架他是通过oid来区分不同的po对象,如果在内存中有两个相同的oid对象,那么hibernate认为他是一个对象
为什么po类属性需要使用包装类型
1:使用基本数据类型,没有办法去描述不存在概念,如果使用包装类型,他就是一个对象,对于对象他的默认值为null.
po类不能使用final修饰(bibernate中get/load的区别)
1: get直接飞到了一个持久化类型对象 他是立即查询操作
load他得到的是持久化类型代理对象(子类对象).它采用了一种延迟策略来查询数据
2: get方法在查询不存在的数据值时,返回的是null
load方法在查询不存在的数据值时,会产生异常
b:主键生成策略
hibernate中定义的主键类型包括:自然主键和代理主键
自然主键:具有业务含义 字段 作为主键,比如学号,省份证号
代理主键:不具有业务含义 字段作为主键 仅代表唯一性的字段,例如自增长id,oracle的rowid等
1:increment(hidernate维护的主键)
代理主键 由hibernate 维护一个变量,每次生成主键时自动递增
优点:可以跨平台访问
缺点:不适合高并发访问
2:identity(mysql维护的主键)
代理主键 由底层数据库生成标识符,条件是数据库支持自动增长数据类型
优点:由底层数据库维护,和hibernate无关
缺点:只能支持自动增长的数据库有效 例如mysql
3:sequence(oracle维护的主键)
代理主键 hibernate由底层数据库生成标识符,条件是数据库支持序列.默认使用的序列是 hibernate id
优点:由底层数据库维护 和hibernate无关
缺点:数据库必须支持sequence方案 例如oracle
4:native(选择mysql/oracle主键)
代理主键 根据地层数据库对自动来选择
优点:在项目中如果存在多个数据库时使用
缺点:效率比较低
5:uuid(32位字符串类型)
代理主键 hibernate采用128位的uuid算法来生成标识符,
优点:与数据库无关,方便数据库移植,效率高,不访问数据库就可以直接生成主键,并且他能保证唯一性
缺点:uuid长度大(32位) 占用空间比较大,对应数据库中类型 char varchar
6:assigned
自然主键 由java程序负责生成标识符
尽量在操作中避免手动操作
B:hibernate持久化对象状态
a:瞬时态
概念:
也叫做临时态或自由态,他一般指我们new出来的独享,它不存在 oid,与hibernate session无关联,在数据库中也无记录. 她使用完成后,会被jvm直接回收掉,他只用于信息携带
无oid 与数据中的信息无关联,不存在session管理范围内
b:持久态
概念:
在hibernate session 管理范围内,它具有持久化标识 oid 他的特点,在事务提交前一致是持久态,当他发生改变时,hibernate可以检测到.
有oid 由session管理,在数据中有可能有,也有可能没有.
c:托管态
概念:
也叫做游离态/离线态,它是指持久态对象失去了与session的关联.托管态对象存在oid,在数据库中有可能存在,也有可能不存在.对于托管态对象,他发生改变,hibernate 不能检测到.
C:持久化类三种状态切换
a:判断持久化类对象三种状态:
1:是否有oid
2:判断是否与session关联
b: 瞬时态:(new出来)
瞬时-->持久
语法:
save saveOrUpdate
瞬时-->游离(托管)
手动设置一个oid
c: 持久态(由session管理的)
持久态-->瞬时
语法:
delete()//相当于直接删除 被删除后持久化对象不再建议使用
持久态-->托管(游离)
语法:
Evict(清除一级缓存中指定的一个对象)
clear(清除一级缓存)
close(关闭,清空一级缓存)
注意:
session 他的缓存就是所说的一级缓存
d: 托管态(无法直接获取)
托管-->瞬时
直接将oid删除
托管-->持久
语法:
update() saveOrUpdate() lock()过时
D:Hibernate的一级缓存
概念:
hibernate的一级缓存指的就是session缓存
在session中定义了一系列的集合来存储数据,他们构成session缓存.
只要session没有关闭,他就会一直存在.
当我们通过个hibernate中的session提供一些api 例如save get update等进行操作时,
就会将持久化对象保存到session中,当下一次去查询缓存中具有的对象(oid值来判断),
hibernate的以及缓存存在的目的就是为了减少对数据库的访问.
在hibernate中还有一个二级缓存,他是sessionFactory连接池级别的缓存.
注意:持久化对象具有自动更新数据库的能力
E:一级缓存常用的api
a:一级缓存的特点
1:当我们通过session的save update saveOrUpdate进行操作时,如果一级缓存中没有对象,会将这些对象从数据库中查询到,存储到一级缓存.
2:当我们通过session的load,get,query 的list等方法进行操作时,会先判断一级缓存中是否存在,如果没有才会从数据库中获取,并且将查询的数据存储到一级缓存中.
3:当调用session的close方法时,session缓存清空
b:一级缓存常用的api
clear():清空一级缓存
evict():清空一级缓存中指定的数据
refrech():重新查询数据库,用数据库里的值来更新一级缓存与快照区.同步session缓存
update:
主要针对于托管对象,持久化对象具有自动更新能力.
当操作的对象是一个托管对象时,他会将托管对象转换成一个持久化对象在进行操作
如果在session中出现两个相同的oid对象,会产生异常
托管对象的oid在数据表中不存在,会报异常.在实际开发中,推荐使用持久化对象进行操作
saveOrUpdate:
如果对象是一个瞬时对象 那么他执行的是save操作
如果对象是一个托管对象 那么他执行的是update操作
如果对象是一个持久对象 那么他直接返回
delete:
删除一个托管对象,与session关联,再删除.
注意:如果执行delete操作,先删除一级缓存,再删除数据库中的数据
F:Hibernate的关联映射 数据对象的三种关系
概念:
hibernate框架基于orm设计思想,他将关系型数据库中的表与我们java中的类进行映射,一个对象对应表中的一条记录.
a:一对一(实体类创建时,互相持有一个类的对象.)
1:唯一外键对应
在任意一方添加一个相对应的映射关系
2:主键对应
通过相同属性进行映射
注意:在java实体类中拥有一个互相的对象就可以.
b:一对多(多对一)
对于一对多或者多对一,我们在建表时的原则是,在多的一方添加外键描述关联关系.
注意:list集合有序,可重复. set集合无序,不可重复
c:多对多
对于多对多关系,在描述时会通过一张中间表来描述其对应关系