Hibernate持久化对象:
★持久化类应该遵守的规则:
Hibernate操作的持久化类基本上都是普通、传统的Java对象(POJO)。
1 提供一个无参数的构造器
2 提供一个标识属性:标识属性通常映射数据库表的主键字段
3 为持久化类的每个属性提供setter和getter方法
4 使用非final的类:生成代理,进行性能优化
5 重写equals()和hashCode()方法:判定持久化对象的唯一性
★持久化对象的状态:
◇瞬态:对象由new操作符创建,并且尚未与Hibernate Session关联的对象
◇持久化:持久化实例在数据库中有对应的记录,并拥有一个持久化标识
◇脱管:某个实例曾经处于持久化状态,但随着与之关联的Session被关闭,该对象就变成脱管状态。
★改变持久化对象状态的方法:
◇瞬态->持久化状态
将obj对象变为持久化状态,该对象的属性被保存到数据库
Serializable save(Object obj)
Serializable save(Object obj,Object pk)
void persist(Object obj)
void persist(Object obj,Object pk)
save与persist方法区别:
1 有无返回值:save方法会返回该持久化对象的标识属性值,persist方法无返回值
2 是否立即提交数据库:save方法是,persist否
根据主键装载持久化实例:
load():具有延迟加载功能
get():立即访问数据库,当加载的记录不存在时,返回null
★Session的保存、删除、更新和查询方法:
◇Session的save()方法:使用一个临时对象转变为持久对象。
方法签名:public Serializable save(Object object) throws HibernateException; 它完成以下操作:
1) 把持久化类的实例加入到缓存中,使它变为持久化对象。
2) 选用映射文件指定的标识符生成器为持久化对象分配唯一的OID。
3) 计划执行一个insert语句,把持久化对象当前的属性值组装到insert 语句(SQL DML)中。值得注意的是,save()方法并不是立即执行SQL insert语句。只有当Session清理缓存时,才会执行SQL insert语句。
另外,需要注意的是:Hibernate通过持久化对象的OID来维持它和数据库相关记录的对应关系。所以当持久化的实例处于持久化状态时,不允许程序随意修改它的OID。其实,无论java对象处于瞬时状态、持久化状态还是脱管状态,程序都不应该修改它的OID。
◇Session的update()方法:使一个脱管对象转变为持久化对象。
方法签名:public void update(Object object) throws HibernateException; 它完成以下操作:
1) 把脱管对象重新加入到Session缓存中,使它变为持久化对象。
2) 计划执行一个update语句。值得注意的是,Session只有在清理缓存的时候才会执行update语句,并且在执行时才会把持久化对象当前的属性值组装到update语句中。
◇Session的saveOrUpdate()方法:
方法签名:public void saveOrUpdate(Object object) throws HibernateException ; saveOrUpdate()方法同时包含了save()与update()方法的功能,如果传入的参数是瞬时对象,就调用save()方法;如果传入的参数是脱管对象,就调用update()方法;如果传入的参数是持久化对象,方法就直接返回。那么,saveOrUpdate()方法如果判断一个对象处于瞬时状态不是脱管状态呢?如果满足以下情况之一,Hibernate就把它作为临时对象:
1) Java对象的OID取值为null。
2) Java对象具有version属性,并且取值了null。
3) 在映射文件中为<id>元素设置了unsaved-value属性,并且OID取值与unsaved-value属性值匹配。
4) 在映射文件中为<version>元素设置了unsaved-value属性,并且version属性取值与unsaved-value属性值匹配。
5) 自定义了Hibernate的Interceptor实现类,并且Interceptor的isUnsaved()方法返回Boolean.TRUE。
◇Session的delete()方法:
方法签名:public void delete(Object object) throws HibernateException; delete()方法用于从数据库中删除与Java对象对应的记录。如果传入的参数是持久化对象,Session就计划执行一个delete语句。如果传入的参数是游离对象,先使游离对象被Session关联,使它变为持久化对象,然后计划执行一个delete语句。值得注意的也是,Session只有在清理缓存的时候才会执行delete语句。
★通过主键ID取得数据对象:
◇ Session的get()方法:
方法签名:public Object get(Class clazz, Serializable id) throws HibernateException; 根据给定的OID从数据库中加载一个持久化对象,若数据库中不存在与OID对应的记录,此方法返回null。
get()方法的执行顺序如下:
1) 首先通过id在session缓存中查找对象,如果存在此id主键值的对象,直接将其返回。如果不存在,将进行第2步。
2) 在二级缓存中查找,找到后将其返回。
3) 如果在session缓存和二级缓存中都找不到此对象,刚从数据库加载拥有此id的对象。如果数据库也不存在这个拥有此id的对象,则返回null。
◇ Session的load()方法:
方法签名:public Object load(Class theClass, Serializable id) throws HibernateException; 根据给定的OID从数据库中加载一个持久化对象,若数据库中不存在与OID对应的记录,此方法将抛出 org.hibernate.ObjectNotFoundException异常。
对于get和load的根本区别,一句话,hibernate对于load方法认为该数据在数据库中一定存在,可以放心的使用代理来延迟加载,如果在使用过程中发现了问题,只能抛异常;而对于get方法,hibernate一定要获取到真实的数据,否则返回null。