1.Hibernate 持久化类与主键生成策略
--什么是持久化?PO persistent Object
对于Hibernate中的PO规则
1.必须提供一个无参数的public构造方法
2.所有的属性要private,对外提供public的get、set方法
3.在po类中必须提供一个标识属性,让它与数据库中的主键对应,我们管这个属性叫OID。
4.PO类中的属性尽量使用基本的数据类型包装类。
int -> integer; double -> Double; float -> Float;
5.PO类它不能使用final修饰符。
OID作用:OID指的是与数据库中的表的主键对应的属性。
Hibernate框架它是通过OID来区分不同的PO类,如果在内存中有两个相同的OID对象,那么Hibernate认为他们是同一个对象。
OID对象,那么Hibernate认为它们是一个对象。
为什么PO类属性它要使用包装类型?
使用基本类型是没有办法描述不存在概念,如果使用包装类类型,他就是一个对象,对于对象它的默认值是null。
PO类不可以使用final修饰?(Hibernate中的get、load方法的区别)
Get、Load方法它们都是根据id去查询对象
1.get直接得到了一个持久化类型的对象,它是立即查询操作。
Load它得到的是持久化类的代理类型对象,它采用了一种延迟策略来查询数据。
2.get方法在查询的时候,如果不存在返回null
load方法在查询时,如果不存在会产生异常。
// 测试get、load方法
@Test
public void test09(){
Session session = hibernateUtils.openSession();
session.beginTransaction();
// 操作
Csutomer csutomer = session.get(Csutomer.class, 30);
System.out.println(csutomer);//cn.itheima.domain.Csutomer
Csutomer sCsutomer = session.load(Csutomer.class, 30);
System.out.println(sCsutomer);//cn.itheima.domain.Csutomer_$$_jvst54e_0
session.getTransaction().commit();
session.close();
}
2.Hibernate持久化类与主键生成策略
Hibernate中定义 的主键类型包括:自然主键和代理主键
自然主键:具体业务含义字段作为主键,比如:身份证号码。
代理主键:不具有业务含义,字段作为主键(例如 自增ID),比如:mysql自增主键,
oracle序列生成的主键,UUID()方法生成的唯一序列串。
## 在开发中使用代理主键 ##
主键生成器 --- 描述:
Increment:代理理主键。由Hibernate维护一个变量,每次生成主键是自动递增。问题:如果有多个应用访问一个数据库,由于每个应用维护自己的主键,所以,此时主键可能冲突。建议不采用。优点:可以方便跨平台。缺点:不适合高并发。
identity:代理主键。由底层数据库生成标识符。条件是数据库支持自动增长数据类型。比如mysql的自增主键,Oracle不支持主键自动生成。如果数据库支持自增建议采用。
优点:由底层数据库维护,与Hibernate无关。缺点:只能对支持自动增长的数据库有效,例如mysql。
sequence : 代理主键。 Hibernate根据底层数据库序列生成标识符。条件是数据库支持序列。比如Oracle的序列。如果数据库支持建议采用。
优点:由底层数据库维护,和Hibernate无关。缺点:数据库必须支持sequence,比如oracle。
native : 代理主键:根据底层数据库对自动来选择identity、sequence、hilo由于生成主键策略的控制权由Hibernate控制,建议不采用。
优点:在项目中如果存在多个数据库时使用 。 缺点:效率比较低。
uuid : 代理主键。Hibernate采用128位uuid算法生成标识符。该算法能够在网络环境中生成唯一的字符串标识符。此策略可以保证生成主键的唯一性,并且提供最好的数据库插入性能和数据库平台的无关性。
优点:与数据库无关,方便数据库移植,效率高,不访问数据库就可以直接生成主键值,并且他能保证唯一性。
缺点:uuid长度大(32位),占用空间比较大,对应数据库 char varchar。
assigned : 自然主键,由java程序猿负责生成标识符,不建议采用。
3.Hibernate持久化对象状态
--瞬时态
一般指我们new出来的对象,不存在OID,与Hibernate session无关联,在数据库中也无记录。它使用完成后,会被JVM直接回收掉,它只是用于信息的携带。
简单说,无OID与数据库中的信息无关联,不在session管理范围内。
--持久态
在Hibernate session管理范围内,它具体持久化标识OID,它的特点。在事务未提交前只是持久态。简单说,有OID有session管理,在数据库中有可能有,也可能没有。当它发生改变时,Hibernate可以检测到。
--托管态
指持久态对象失去了与session的关联,托管态对象它存在OID,在数据库中有可能存在,也有可能不存在。对于托管态对象,它发生改变时,Hibernate不能检测到。
// 测试持久化对象三种状态
@Test
public void test10(){
Session session = hibernateUtils.openSession();
session.beginTransaction();
// 操作
Csutomer csutomer = new Csutomer();//瞬时态(无OID与session无关联)
csutomer.setName("tommy");
csutomer.setAddress("jiaixng");
session.save(csutomer);//建立了csutomer与session关联关系。他是持久态有OID。
session.getTransaction().commit();
session.close();
System.out.println(csutomer.getName());//断开了与session的关联,它是托管态,有OID
}
4.持久化类的三种状态切换
--判断持久化类对象的三种状态:
1.是否有OID
2.判断是否与session关联。
1.瞬时态(new 出来的)
瞬时-->持久 save saveOrUpdate
瞬时-->托管 手动设置OID。
2.持久态,由session管理
持久 --> 瞬时 delete(),被删除后持久化对象不在建议使用。
持久 --> 托管 ,session他的缓存就是所说的一级缓存。Evict清除一级缓存中指定的一个对象。clear清空一级缓存。close关闭请空一级缓存。
3.托管态,无法直接获取
托管 --> 瞬时 直接将OID删除。
托管 --> 持久 update saveOrUpdate lock过时。