一、持久化类的要求
提供一个无参构造器:Hibernate可使用Constructor.newInstance()来创建持久化类的实例
提供一个标识属性:标识属性通常映射数据库表的主键字段(建议使用基本类型的包装类型作为标识属性的类型)尽量避免使用基本数据类型
为持久化类的每个属性提供setter、getter方法
使用非final的类
重写equlas、hashCode方法:如需把持久化类的实例放入Set中
二、持久化对象的状态
瞬态:对象由new创建,且尚未与Hibernate Session关联的对象;瞬态对象不会被持久化到数据库中,也不会被赋予持久化标识
持久化:持久化实例在数据库中有对应的记录,并拥有一个持久化标识(identifier); 持久化对象必须与指定的Hibernate Session关联
托管:某个实例曾处于持久化状态,但随着与之关联的Session被关闭,该对象就变成托管状态;托管对象的引用依然有效,对象可继续被修改
三、改变持久化对象状态
瞬态---》持久化状态(Session的方法):
Serializable save(Object obj):将obj对象变为持久化状态,该对象的属性将被保存到数据库
Serializable save(Ojbect obj,Object pk):将obj对象保存到数据库并指定主键值
void persist(Object obj):将obj对象转化为持久化状态,该对象的属性将被保存到数据库
void persist(Object obj,Object pk):将obj对象保存到数据库并指定主键值
save方法会立即将持久化对象对应的数据插入数据库;
persist方法不会立即转换成insert语句,保证当它在一个事物外部被调用
当把一个瞬态实体变成持久化状态时,Hibernate会在底层对应的生成一条insert语句把实体对应的数据记录插入数据表
load()加载一个持久化实例,根据持久化类的标识属性值加载持久化实例(根据主键从数据表中加载一条新记录):
get()加载一个持久化实例(根据主键装载持久化实例)
News n = session.load(News.class , new Integer(pk));
pk:加载的持久化实例的标识属性
load():不会立即访问数据库;如无对应的记录,可能抛出HibernateException异常;若在类映射文件中指定了延迟加载,则返回一个未初始化的代理对象(可理解为持久化对象的替身),该代理对象并没有装载数据记录,直到程序调用该代理对象的某方法时,Hibernate才会去访问数据库;具有延迟加载功能
get(): 立即访问数据库;若无对应的记录,则返回null;
执行load、get方法加载实体时,Hibernate会在底层对应的生成一条select语句,这条select语句带有“where<主键列>=<标识属性值>”子句;都是根据主键加载持久化实例
托管状态---》持久化状态:
当修改托管对象的状态后,应用新的Session来保存这些修改,可通过update()、merge()、updateOrSave()来保存:
Student student = firstSess.load(Student.class,new Integer(20)); firstSess.close(); // 第一个Session已关闭 Student.setTitle(“新标题”); // 修改托管状态下的持久化对象 Session secondSess = ... // 打开第二个Session secondSess.update(student); // 保存托管对象所做的修改
当使用update来保存对持久化对象所做的修改时,如果不清楚该对象是否曾经持久化过,可用updateOrSave()方法
merge方法也可将托管对象所做的修改保存到数据库,merge与update方法最大的区别:merge方法不会持久化给定对象(当执行sess.update(a)后,a对象将会变成持久化状态;而执行sess.merge(a)后,a对象依然不是持久化状态,a对象依然不会被关联到Session上)
修改持久化实例:
Studentstudent = (Student) session.load(Student.class, newInteger(22)); student.setName("HHH"); session.flush();
删除持久化实例:
Studentstudent = Session.load(Student.class,new Integer(PK)); Session.delete(student);