数据库主键分为两种:代理主键和自然主键 ----> 代理主键使用居多
代理主键:不具有业务含义的字段作为主键,例如自增长的id, uuid
自然主键:具有业务含义的字段作为主键,例如订单编号
主键约束类型:increment, identity, sequence , native ,uuid ,assigned
increment: 不科学,有线程问题, 原理 select max(id)+1
identity: mysql 自动增长
sequence: oracle 序列增长
native:会自动判断数据库,判断使用 identity还是sequence
uuid: string类型,生成代理主键
assigned:唯一的一个自然主键设置方式,手动设置主键的值
po:设置属性类型的时候,尽量使用包装类,因为包装类不赋值返回null,非包装类有初始值
OID(Object identifier):对象标识,用来标识唯一对象,是实体类中与数据库主键保持一致,Hibernate框架根据OID标识,判断是否为同一个对象
瞬态/临时态:通常new关键字创建出来的对象,未与session关联,没有OID
持久态:在数据库存在对应的实例,拥有持久化标识OID,与session关联(受session管理)
脱管态/游离态:当session关闭后,持久状态对象与session断开关联,称为脱管对象,此时没有与session关联,也有OID
三种状态互相转换:
瞬时对象:
如何直接获取 --- new出来
转换到持久态 --- save,saveOrUpdate 保存操作
转换到脱管态 --- setId , 设置OID持久化标识(这个id必须是数据库中存在的)
持久对象
如何直接获得 --- 通过session查询方法从数据库获得, get,load,createQuery,creteSQLQuery,createCriteria
转换到瞬时态 --- delete操作,数据表不能再对应的数据,其实还有id只是不叫OID
转换到托管态 --- close关闭session,evict,clear,从session中清除对象
脱管对象
如何直接获得 --- 无法直接通过查询数据库获得,必须通过瞬时对象或者持久对象转换获得
转换到瞬时态 --- 将id设置为null,或者手动将数据的对应数据删掉,或者将id改成数据库不存在的
转换到持久态 --- update,saveOrUpdate, 对象重新放入session,重新与session关联
session的一级缓存
只要session的生命周期没有结束,session中的数据就不会清空
只要是持久态对象,都会保存在一级缓存(与session关联的本质一样,只有和session关联,才会持久态)
get和load获取数据,先去缓存中查看,如果缓存中有,从缓存中获取,如果没有去数据库中查找
get:立即发送sql语句
load:生成代理对象,延迟抓取,只有获取id以外的属性时,才会发送sql语句
Query查询会比较缓存和快照,如果一致取数据库直接取数据,如果缓存中持久化对象的属性已经发生变化,则先刷出缓存执行update,然后查询Query不从缓存中读取数据,但是会比较缓存和快照数据是否一致
flush() : 修改数据库和缓存一样(提交缓存中数据到数据库,执行update)
refresh(): 刷新缓存根数据库一样(重新执行select语句,刷新缓存,与数据库一样)
一对多关系映射
<hibernate-mapping package= "cn.domin">
<class name= "Order" table ="p_order">
<id name= "id">
<generator class= "native"></generator >
</id>
<property name= "name"></property >
<property name= "price"></property >
<!-- 映射关系: 多对一 -->
<many-to-one name= "customer" class ="Order" column="cid" ></many-to-one>
</class>
</hibernate-mapping>
<hibernate-mapping package= "cn.domin">
<class name= "Customer" table ="p_customer">
<id name= "id">
<generator class= "native"></generator >
</id>
<property name= "name"></property >
<!-- 映射关系: 一对多-->
<set name= "orders">
<key column= "cid"></key >
<one-to-many class= "Customer" />
</set>
</class>
</hibernate-mapping>
级联操作:cascade: save-update,delete
级联保存,删除,的对象一定要是持久态,否则没有效果,设置某个对象级联,然后只操作这个对象就会执行相连的对象操作
级联作用:
可以使持久态对象“关联”瞬时态对象,自动会隐式执行save操作,变为持久态
可以使持久太对象“关联”托管态对象,自动会隐式执行update操作,变为持久态
在实际开发中,一对多模型中,一方一般是主动的一方(多方要依赖一方),如果配置级联,通常在一方进行配置
因为多方需要引用一方的主键作为外键使用
一般在业务开发中,不需要两端都配置级联,(多方尽量不要配置级联,尽量在一方配置级联)
对象导航:其实是依赖于级联
对象导航概念:通过一个对象的保存操作,可以自动导航到另外一个关联对象的保存操作
一对多级联保存: one-to-many 或者 many-to-one
< set name ="orders" cascade ="save-update,delete" inverse ="true">
inverse:外键维护权问题,值应用于集合,在业务开发中一般在一方放弃维权
true: 放弃外键维护权
false:不放弃(默认)
多对多关系映射
<-- 映射关系
设置中间表 p_s_c
sid 对应中间表student的外键名称
class: 表示集合属性名称对应的实体类
cid: 对应中间表中Course对应的外键名
-->
<set name="courses" table= "p_s_c">
<key column= "sid"></key >
<many-to-many class= "cn.manytomany.Course" column="cid" ></many-to-many>
</set >
1
网友评论