Hibernate是一个纯粹的O/R Mapping框架。对于程序开发者而言,眼里只有对象、属性、无须理会底层数据表、数据列等概念。
1.持久化类的要求
- 提供无参构造器
- 提供一个标识属性:建议使用基本类型的包装类型作为标识属性的类型。
- 为持久化类的每个成员变量提供setter和getter方法
- 使用非final类
- 重写equals()和hashCode()方法:如果需要把持久化类的实例放入Set中,则应该为该持久化类重写equals()和hashCode()方法。
2.持久化的状态
- 瞬态:对象由new操作符创建,且尚未与Hibernate Session关联的对象被认为处于瞬态。瞬态对象不会被持久化到数据库中,也不会被赋予持久化标识。如果程序中失去了瞬态对象的引用,瞬态对象将被垃圾回收机制销毁。使用Hibernate Session可以将其变为持久化状态。
- 持久化:持久化实例在数据库中有对应的记录,并拥有一个持久化标识。
- 脱管:某个实例曾经处于持久化状态,但随着与之关联的Session被关闭,该对象就变成脱管状态。脱管对象的引用依然有效,对象可继续被修改。如果重新让脱管对象与某个Session关联,这个脱管对象会重新转换为持久化状态,而脱管期间的改动不会丢失,也可被写入数据库中。
3.改变持久化对象状态的方法
(1.)持久化实例
为了让瞬态对象转换为持久化状态:
- Serializable save(Object obj):将obj对象变为持久化状态,该对象的属性将被保存到数据库。
- void persist(Object obj):将obj对象变为持久化状态,该对象的属性将被保存到数据库
- Serializable save(Object obj,Object pk):将obj对象保存到数据库,保存到数据库时,指定主键值。
- void persist(Obejct obj,Object pk):将obj对象变为持久化状态,保存到数据库时,指定主键值。
将一个瞬态实体变成持久化状态时,Hibernate会在底层对应生成一条inset语句,这条语句负责把该实体对应的数据记录插入数据表。
save()和persist()方法区别:使用save()方法保存持久化对象时,该方法返回该持久化对象的标识属性值(即对应记录的主键值);但使用persist()方法来保存持久化对象时,该方法没有任何返回值。save()方法会立即将持久化对象对应的数据插入数据库,而persist()则保证当它在一个事务外部被调用时,并不立即转换成inset语句。
(2.)根据主键加载持久化实体
程序可以通过load()来加载一个持久化实例,这种加载就是根据持久化类的标识属性值加载持久化实例—其实质就是根据主键从数据表中加载一条记录。
News n = sess.load(News.class,pk);
如果希望在某对象中创建一个指向另一个对象的关联,又不想在数据库中装载该对象的同时立即装载所关联的全部对象,延迟加载的方式就非常有用了。
get()方法也用于根据主键加载持久化实例,但get()方法会立刻访问数据库,如果没有对应的记录,get()方法返回null,而不是返回一个代理对象。
load()或get()方法加载实体时,Hibernate会在底层对应地生成一条select语句,这条select语句带有”where <主键列>=<标识属性值>”子句,表明将会根据主键加载。
区别:使用load()方法将具有延迟加载功能,load()方法不会立即访问数据库,当试图加载的记录不存在时,load()方法可能返回一个未初始化的代理对象;而get()方法总是立即访问数据库,当试图加载的记录不存在时get()方法将直接返回null。
(3.)更新持久化实体
一旦加载了该持久化实例后,该实体就处于持久化状态,在代码中对持久化实例所做的修改被保存到数据库。
程序对持久化实例所做的修改会在Session flush之前被自动保存到数据库,无须程序调用其他方法来将修改持久化。修改对象最简单的方法就是在Session处于打开状态时load()它然后直接修改即可。
如果调用持久化实体的setter方法改变了它的属性,Hibernate会在Session Flush之前生成一条update语句,这条update语句带有”where <主键列>=<标识属性值>”子句。
Hibernate通常的处理流程:从数据库里加载记录->将信息发送到表现层供用户修改->将所做修改重新保存到数据库。
(4.)更新脱管实体
当程序修改脱管对象的状态后,程序听该显示地使用新的Session来保存这些修改。
当需要使用update()来保存程序对持久化对象所做的修改时,如果不清楚该对象是否曾经持久化过,那么程序可以选择使用updateOrSave()方法,该方法自动判断该对象是否曾经持久化过,如果曾经持久化过,就执行update()操作;否则将执行save()操作。
(5.)删除持久化实体
通过Session的delete()方法来删除该持久化实例,一旦删除了该持久化实例,该持久化实例对应的数据记录也被删除。