2007-02-05 23:10:55
属性
1 unsaved-value:对级联对象进行数据保存时,Hibernate将根据这个值来判断对象是否需要保存;先从级联对象中取出id,如果id和 unsave-value值相等,则认为对象尚未保存,否则认为对象已经保存(这里的保存指的是insert,而不是update)
;在隐式保存的情况下,Hibernate用目标对象的id值和此值比较,如果相等则insert,否则不insert
2 hbm.xml文件的class标签中有一个polymorphism="explicit"属性,它的作用是:声明一个显式多态关系,声明为显式多态的类只有在代码中(如:list object=createQuery("from TuserProfile").list();这里显式指明了TuserProfile类)明确指定类名的时候才会返回此类实例;
如果要返回对应整个数据库中所有库表记录的数据对象,可用: List obj=createQuery("from object").list();但不会返回在映射文件中具有polymorphism="explicit"定义的类的实例
3 inverse:用于在设置双向一对多关系时设置维护两个实体关系的一方,inverse=false的一方负责维护双方关系;在one-to-many关系中,常将many一方设为false方
4 cascade:指的是当主控方执行操作时,关联对象(被动方)是否同步执行同一操作。例如对主控对象调用save-update或delete方法时, 是否同时对关联对象(被动方)进行sava-update或delete;设定为all则代表无论主控方执行任何操作 (Insert/update/delete...)都对其关联类时行同样的操作
;根据此属性的设置对相关联的对象采取相应的操作
cascade="all-delete-orphan"处理方式:
当保存当前对象时保存相关联的对象,相当于cascade="save-update"
当删除当前对象时删除相关联的对象,相当于cascade="delete"
当双方存在父子关系时,如果解除了子与父的关系则删除和父方解除关系的子方记录
(当关联双方存在父子关系时,就可以把父方的cascade设为all-delete-orphan)
5 在<property>标签中的access属性说明:
形式<property name="name" column="name" access="field/property"/>
access默认为property,意思是:Hibernate不是直接访问持久化类中的name属性,而是访问setName()和getName()方法;
access="field",意思是:Hibernate不访问setName()和getName()方法,而是直接访问持久化类中的name属性
6 hbm.xml文件的class标签中有一个polymorphism="explicit"属性,它的作用是:声明一个显式多态关系,声明为显式多态的类只有在代码中(如:list object=createQuery("from TuserProfile").list();这里显式指明了TuserProfile类)明确指定类名的时候才会返回此类实例;
如果要返回对应整个数据库中所有库表记录的数据对象,可用: List obj=createQuery("from object").list();但不会返回在映射文件中具有polymorphism="explicit"定义的类的实例
1 unsaved-value:对级联对象进行数据保存时,Hibernate将根据这个值来判断对象是否需要保存;先从级联对象中取出id,如果id和 unsave-value值相等,则认为对象尚未保存,否则认为对象已经保存(这里的保存指的是insert,而不是update)
;在隐式保存的情况下,Hibernate用目标对象的id值和此值比较,如果相等则insert,否则不insert
2 hbm.xml文件的class标签中有一个polymorphism="explicit"属性,它的作用是:声明一个显式多态关系,声明为显式多态的类只有在代码中(如:list object=createQuery("from TuserProfile").list();这里显式指明了TuserProfile类)明确指定类名的时候才会返回此类实例;
如果要返回对应整个数据库中所有库表记录的数据对象,可用: List obj=createQuery("from object").list();但不会返回在映射文件中具有polymorphism="explicit"定义的类的实例
3 inverse:用于在设置双向一对多关系时设置维护两个实体关系的一方,inverse=false的一方负责维护双方关系;在one-to-many关系中,常将many一方设为false方
4 cascade:指的是当主控方执行操作时,关联对象(被动方)是否同步执行同一操作。例如对主控对象调用save-update或delete方法时, 是否同时对关联对象(被动方)进行sava-update或delete;设定为all则代表无论主控方执行任何操作 (Insert/update/delete...)都对其关联类时行同样的操作
;根据此属性的设置对相关联的对象采取相应的操作
cascade="all-delete-orphan"处理方式:
当保存当前对象时保存相关联的对象,相当于cascade="save-update"
当删除当前对象时删除相关联的对象,相当于cascade="delete"
当双方存在父子关系时,如果解除了子与父的关系则删除和父方解除关系的子方记录
(当关联双方存在父子关系时,就可以把父方的cascade设为all-delete-orphan)
5 在<property>标签中的access属性说明:
形式<property name="name" column="name" access="field/property"/>
access默认为property,意思是:Hibernate不是直接访问持久化类中的name属性,而是访问setName()和getName()方法;
access="field",意思是:Hibernate不访问setName()和getName()方法,而是直接访问持久化类中的name属性
6 hbm.xml文件的class标签中有一个polymorphism="explicit"属性,它的作用是:声明一个显式多态关系,声明为显式多态的类只有在代码中(如:list object=createQuery("from TuserProfile").list();这里显式指明了TuserProfile类)明确指定类名的时候才会返回此类实例;
如果要返回对应整个数据库中所有库表记录的数据对象,可用: List obj=createQuery("from object").list();但不会返回在映射文件中具有polymorphism="explicit"定义的类的实例
方法
1 加载数据的get和load方法区别:
a 如果未能发现符合条件的记录,get方法返回null,load方法抛出一个ObjectNotFoundException异常
b load可以返回实体的代理类实例,get永远直接返回实体类
代理类实例:
实体类:
c load要在内部缓存和二级缓存中搜索现有数据,get则仅在内部缓存中进行数据查找(根据id查找),如果在内部缓存中没有找到数据则直接从数据库中读取
内部缓存(一级缓存):其中保持了session当前所有关联实体的数据
二级缓存:存在于SessionFactory层次,由当前所有本SessionFactory构造的session实例共享
2 session.find(hql,parameterValue,Hibernate Type of parametervlaue)和session.iterator(hql,parameterValue,Hibernate type of parameterValue) 方法的区别:
session.find()返回的是List集合;session.find() 执行相应SQL后返回记录并构造相应的实体对象,再将其纳入缓存.find()不会对缓存进行数据查询,而是直接从数据库取记录,对于缓存只写不读
session.iterator()返回的是Iterator集合;执行N+1次查询出所有符合条件的记录,首先查询满足条件的记录id,再根据id 查询所有记录;iterator首先在本地缓存中根据id查找对应的实体对象是否存在(类似session.load()),若存在则以此数据对象作为结 果返回;若未找到,则执行相应SQL语句从数据库获得对应的记录,并构建完整数据对象,再将其纳入缓存
3 缓存对象的移除
session.evict(user)----从一级缓存中移除对象
sessionFactory.evict(Tuser.class,user.getId())-------从二级缓存中移除对象;二级缓存可以设定最大数据缓存量,达到峰值时自动对缓存中的较老数据进行移除;也可以手工移除(如前)
4 session.save()先在一级缓存中查询要保存的对象,若找到则认为对象处于持久状态;不会把对象放在二级缓存,而是放在一级缓存
session.update()先在一级缓存中查询要保存的对象,若找到则认为对象处于持久状态;将在session.flush()时执行update的SQL语句(transaction.commit在真正提交数据库事务前会调用session.flush)
saveorupdate()无需用户判断对象的状态,其自动判断再执行save或者update
5 saveorupdate()方法说明:该方法包含了save()与update()方法的功能,如果传入的参数是临时对象,就调用save()方法,如 果传入的参数是游离对象,就调用update()方法,如果传入的是持久化对象,那就直接返回.saveorupdate()方法如何判断一个对象是处于 临时状态还是游离对象根据的是以下条件,满足其一即可:
1.java对象的ID取值为null
2.java对象具有version属性并且取值为null
3.在映射文件中为<id>元素设置了undaved-value属性,并且ID取值与undaved-value属性值匹配。
4.在映射文件中为version属性设置了unsaved-value属性,并且version属性取值与unsaved-value属性值匹配.
5.自定义了Hibernate的Interceptor实现类,并且Interceptor的isUnsaved()方法返回true.
1 加载数据的get和load方法区别:
a 如果未能发现符合条件的记录,get方法返回null,load方法抛出一个ObjectNotFoundException异常
b load可以返回实体的代理类实例,get永远直接返回实体类
代理类实例:
实体类:
c load要在内部缓存和二级缓存中搜索现有数据,get则仅在内部缓存中进行数据查找(根据id查找),如果在内部缓存中没有找到数据则直接从数据库中读取
内部缓存(一级缓存):其中保持了session当前所有关联实体的数据
二级缓存:存在于SessionFactory层次,由当前所有本SessionFactory构造的session实例共享
2 session.find(hql,parameterValue,Hibernate Type of parametervlaue)和session.iterator(hql,parameterValue,Hibernate type of parameterValue) 方法的区别:
session.find()返回的是List集合;session.find() 执行相应SQL后返回记录并构造相应的实体对象,再将其纳入缓存.find()不会对缓存进行数据查询,而是直接从数据库取记录,对于缓存只写不读
session.iterator()返回的是Iterator集合;执行N+1次查询出所有符合条件的记录,首先查询满足条件的记录id,再根据id 查询所有记录;iterator首先在本地缓存中根据id查找对应的实体对象是否存在(类似session.load()),若存在则以此数据对象作为结 果返回;若未找到,则执行相应SQL语句从数据库获得对应的记录,并构建完整数据对象,再将其纳入缓存
3 缓存对象的移除
session.evict(user)----从一级缓存中移除对象
sessionFactory.evict(Tuser.class,user.getId())-------从二级缓存中移除对象;二级缓存可以设定最大数据缓存量,达到峰值时自动对缓存中的较老数据进行移除;也可以手工移除(如前)
4 session.save()先在一级缓存中查询要保存的对象,若找到则认为对象处于持久状态;不会把对象放在二级缓存,而是放在一级缓存
session.update()先在一级缓存中查询要保存的对象,若找到则认为对象处于持久状态;将在session.flush()时执行update的SQL语句(transaction.commit在真正提交数据库事务前会调用session.flush)
saveorupdate()无需用户判断对象的状态,其自动判断再执行save或者update
5 saveorupdate()方法说明:该方法包含了save()与update()方法的功能,如果传入的参数是临时对象,就调用save()方法,如 果传入的参数是游离对象,就调用update()方法,如果传入的是持久化对象,那就直接返回.saveorupdate()方法如何判断一个对象是处于 临时状态还是游离对象根据的是以下条件,满足其一即可:
1.java对象的ID取值为null
2.java对象具有version属性并且取值为null
3.在映射文件中为<id>元素设置了undaved-value属性,并且ID取值与undaved-value属性值匹配。
4.在映射文件中为version属性设置了unsaved-value属性,并且version属性取值与unsaved-value属性值匹配.
5.自定义了Hibernate的Interceptor实现类,并且Interceptor的isUnsaved()方法返回true.
实体对象的三种状态
java中,对象不引用任何对象且不被任何对象引用时,就会被JVM回收,此时该对象才结束生命周期.
session缓存:session缓存其实就是session的实现类sessionImp中定义的Map集合,以对象ID为键,以对象为值的形式保存.
java中,对象不引用任何对象且不被任何对象引用时,就会被JVM回收,此时该对象才结束生命周期.
session缓存:session缓存其实就是session的实现类sessionImp中定义的Map集合,以对象ID为键,以对象为值的形式保存.
1 Transient(自由状态):刚刚用new语句创建,还没有被持久化,不处于session的缓存中。即实体对象在内存中是自由存在的,它与数据库中的记录无关;处于临时状态的java对象被称为临时对象.
特征:1.不处在session的缓存中,也可以说,不被任何一个session实例关联.
2.在数据库中没有对应的记录.
在以下情况下,java对象进入临时状态:
1.当通过new语句刚创建了一个java对象,它处于临时状态,此时不和数据库中的任何记录对应.
2.session的delete()方法能使一个持久化对象或游离对象转变为临时对象。对于游离对象,delete()方法从数据库中删除与它对应的记录;对于持久化对象,delete()方法从数据库中删除与它对应的记录,并且把它从session缓存中删除.
2 Persistent(持久状态):已经被持久化,加入到了session缓存中。实体对象处于由Hibernate框架所管理的状态,这种状态下,实体 对象的引用被纳入Hibernate实体容器中加以管理;处于Persistent状态的对象,其变更将由Hibernate固化到数据库中
何时变为持久状态:当实体对象处于自由状态时,通过Session.save方法可将其转换为Persistent状态,如果一个实体对象是由 Hibernate加载(如通过Session.load方法获得),那它也处于Persistent状态;处于持久化状态的实体即使没有调用 session.save()方法进行数据持久化,而只用了tx.commit()也会被保存到数据库
持久化对象的特征:
1.位于一个session实例的缓存中,也可以说,持久化对象总是被一个session实例关联.
2.持久化对象和数据库中的相关记录对应
3.session在清理缓存时,会根据持久化对象的属性变化,来同步更新数据库
特征:1.不处在session的缓存中,也可以说,不被任何一个session实例关联.
2.在数据库中没有对应的记录.
在以下情况下,java对象进入临时状态:
1.当通过new语句刚创建了一个java对象,它处于临时状态,此时不和数据库中的任何记录对应.
2.session的delete()方法能使一个持久化对象或游离对象转变为临时对象。对于游离对象,delete()方法从数据库中删除与它对应的记录;对于持久化对象,delete()方法从数据库中删除与它对应的记录,并且把它从session缓存中删除.
2 Persistent(持久状态):已经被持久化,加入到了session缓存中。实体对象处于由Hibernate框架所管理的状态,这种状态下,实体 对象的引用被纳入Hibernate实体容器中加以管理;处于Persistent状态的对象,其变更将由Hibernate固化到数据库中
何时变为持久状态:当实体对象处于自由状态时,通过Session.save方法可将其转换为Persistent状态,如果一个实体对象是由 Hibernate加载(如通过Session.load方法获得),那它也处于Persistent状态;处于持久化状态的实体即使没有调用 session.save()方法进行数据持久化,而只用了tx.commit()也会被保存到数据库
持久化对象的特征:
1.位于一个session实例的缓存中,也可以说,持久化对象总是被一个session实例关联.
2.持久化对象和数据库中的相关记录对应
3.session在清理缓存时,会根据持久化对象的属性变化,来同步更新数据库
3 Detached(游离状态):已经被持久化,但不处于session缓存当中.对应的Session实例关闭之后,此对象就处于游离状态
例:
Tuser user=new Tuser();
user.setName("Emma");//此时实体对象user处于游离状态
Tansaction tx=session.beginTransaction();
session.save(user);//此时实体对象user已经由Hibernate纳入管理容器,处于Persistent状态
tx.commit();
session.close();//(Tag) 实体对象user此时状态为Detached,因为与其关联的session已经关闭
例:
Tuser user=new Tuser();
user.setName("Emma");//此时实体对象user处于游离状态
Tansaction tx=session.beginTransaction();
session.save(user);//此时实体对象user已经由Hibernate纳入管理容器,处于Persistent状态
tx.commit();
session.close();//(Tag) 实体对象user此时状态为Detached,因为与其关联的session已经关闭
3 游离对象的特征:
1.不再位于session缓存中,也可以说,游离对象不实被session关联.
2.游离对象是由持久化对象转变来的,因此在数据库中可能还存在与它对应的记录(只要没删除该记录)
1.不再位于session缓存中,也可以说,游离对象不实被session关联.
2.游离对象是由持久化对象转变来的,因此在数据库中可能还存在与它对应的记录(只要没删除该记录)
4 Transient状态和Detached状态的相同之处:两者都不被session关联.两者的区别:游离对象是由持久对象转变过来的,因此可能在数据 库中还存对应的记录,而临时对象在数据库中没有对应的记录.Detached对象可以再次与某个Session实例相关联而成为Persistent对 象;如下所示
接Tag处:
Transaction tx2=session2.beginTransaction();
session2.update(user);//此时处于Detached状态的user对象再次借助session2由Hibernate纳入管理容器,恢复Persistent状态
user.setName("Eric");
tx2.commit();//由于user对象再次处于Persistent状态,因此其属性变更将自动由Hibernate固化到数据库
5 Transient状态的对象与数据库中记录并不存在对应关系,它所包含的数据信息仅是上面的user.setName("Emma")这点而已; Session.save()执行后,Hibernate对user对象进行了持久化,并为其赋予了主键值,这时user对象就与库表中具备相同id值的 记录相关联;所以,Transient状态的user对象与库表中的数据缺乏对应关系,而Detached状态的user对象,却在库表中存在相对应的记 录(由主键惟一确定),简而言之,Transient状态中的实体对象,无主键信息,而Deatched状态的实体对象包含了其对应数据库记录的主键值;
实体对象从Persistent状态转变为Transient状态一般由session.delete方法完成
接Tag处:
Transaction tx2=session2.beginTransaction();
session2.update(user);//此时处于Detached状态的user对象再次借助session2由Hibernate纳入管理容器,恢复Persistent状态
user.setName("Eric");
tx2.commit();//由于user对象再次处于Persistent状态,因此其属性变更将自动由Hibernate固化到数据库
5 Transient状态的对象与数据库中记录并不存在对应关系,它所包含的数据信息仅是上面的user.setName("Emma")这点而已; Session.save()执行后,Hibernate对user对象进行了持久化,并为其赋予了主键值,这时user对象就与库表中具备相同id值的 记录相关联;所以,Transient状态的user对象与库表中的数据缺乏对应关系,而Detached状态的user对象,却在库表中存在相对应的记 录(由主键惟一确定),简而言之,Transient状态中的实体对象,无主键信息,而Deatched状态的实体对象包含了其对应数据库记录的主键值;
实体对象从Persistent状态转变为Transient状态一般由session.delete方法完成
6 Collection在判断两个对象是否相等的时候,会首先调用对象的hashCode方法,如果hashCode相同的话, 再调用equals方法,如果两次判断均为真,则认为对比的两个对象相等
关联关系
*********************一对多关系中,一方<set>的说明*********************************************
1 当<set>中同时设置lazy和outer-join属性时,如果两者都为false则采用立即检索(因为outer-join="false"则不采用迫切左外连接,但lazy="false"则是指采用立即检索策略);
如果lazy和outer-join其中一个为false另一个为true(不管谁是false谁是true),则以设置为true的那一个为准(即 lazy=true,outer-join=false则是采用延迟检索;相反采用迫切左外连接);如果两者均为true则同lazy=false, outer-join=true(即采用迫切左外连接,outer-join优先级比lazy高);find()方法会忽略outer-join属性,即 outer-join对find方法无效;
如果<set>中设有lazy且<class>中也设有lazy属性,则是以<class>中的为准;
对于get和find方法均是采用立即检索,与lazy的设置无关
2 <set>中的batch-size属性可以理解为:在加载<set>中的<one-to-many>中的class类对象时,要初始化的对象数目,以便在后面再次需要初始化时不需要再访问数据库,从而提高数据访问速度
3 <set>中一般要设置:lazy=true,outer-join="true",batch-size设为要在子方初始化的对象个数(一般为:3-10)
************************多对一关系中,多方的说明******************************888
1(设一方[customer.hbm.xml]的class中的lazy为A;多方[order.hbm.xml]的<many-to-one>中的outer-join为B)
A=true,B=auto,则对于order.hbm.xml的<many-to-one>中的class指向的对象[customer]采用延迟检索,否则用迫切左外连接检索
A=false,B=true,对于order关联的customer采用迫切左外连接检索
A=true,B=false 对于order关联的customer对象采用延迟检索,否则采用立即检索
结论:当A=true时,则B无论设为什么均按照A的设置进行检索,只有当A=false时,才按B的设置进行检索(A的优先级大于B)
2.hibernate.max_fetch_deepth:在迫切左外连接的多层数据表的检索中设置从第一层检索表开始的检索深度(即从第一层检索表开始要检索几层从第一层开始的检索表)
1(设一方[customer.hbm.xml]的class中的lazy为A;多方[order.hbm.xml]的<many-to-one>中的outer-join为B)
A=true,B=auto,则对于order.hbm.xml的<many-to-one>中的class指向的对象[customer]采用延迟检索,否则用迫切左外连接检索
A=false,B=true,对于order关联的customer采用迫切左外连接检索
A=true,B=false 对于order关联的customer对象采用延迟检索,否则采用立即检索
结论:当A=true时,则B无论设为什么均按照A的设置进行检索,只有当A=false时,才按B的设置进行检索(A的优先级大于B)
2.hibernate.max_fetch_deepth:在迫切左外连接的多层数据表的检索中设置从第一层检索表开始的检索深度(即从第一层检索表开始要检索几层从第一层开始的检索表)
Java集合
1.Set 集合中的对象不按特定方式排序,且没有重复对象;
该接口主要有两个实现类HashSet和TreeSet。
HashSet类按照哈希算法来存取集合中的对象,存取速度比较快。HashSet类还有一个子类LinkedHashSet类,它不仅实现了哈希算法,且实现了链表数据结构。TreeSet类实现了SortedSet接口 ,具有排序功能.
为了保证HashSet能正常工作,要求当两个对象用equals()方法比较的结果为相等时,其哈希码也相等;即如果覆盖了equals()方法,也应该覆盖hashCode()方法
1.Set 集合中的对象不按特定方式排序,且没有重复对象;
该接口主要有两个实现类HashSet和TreeSet。
HashSet类按照哈希算法来存取集合中的对象,存取速度比较快。HashSet类还有一个子类LinkedHashSet类,它不仅实现了哈希算法,且实现了链表数据结构。TreeSet类实现了SortedSet接口 ,具有排序功能.
为了保证HashSet能正常工作,要求当两个对象用equals()方法比较的结果为相等时,其哈希码也相等;即如果覆盖了equals()方法,也应该覆盖hashCode()方法
Set set = new HashSet();
String s1 = new String("hello");
String s2 = s1;
String s3 = new String("world");
set.add(s1);
set.add(s2);
set.add(s3);
System.out.println("set的元素个数:" + set.size());//==2
String s1 = new String("hello");
String s2 = s1;
String s3 = new String("world");
set.add(s1);
set.add(s2);
set.add(s3);
System.out.println("set的元素个数:" + set.size());//==2
2 List List的主要特征是其对象以线性方式存储,集合中允许存放重复对象。List接口主要的实现类有:LinkedList,ArrayList。 LinkedList采用链表数据结构,而ArrayList代表大小可变的数组.List接口还有一个实现类Vector,其功能和ArrayList 相似,两者的区别在于:Vector类的实现了同步机制,而ArrayList没有使用同步机制.
List对集合中的对象按索引位置排序,允许按照对象在集合中的索引位置检索对象
List的iterator()方法和Set的iterator()方法均返回Iterator对象,通过Iterator对象,可以遍历集合中的所有对象
List对集合中的对象按索引位置排序,允许按照对象在集合中的索引位置检索对象
List的iterator()方法和Set的iterator()方法均返回Iterator对象,通过Iterator对象,可以遍历集合中的所有对象
3 Map:Map(映射)是一种把键对象和值对象进行映射的集合,其每一个元素都包含了一对键对象和值对象,而值对象仍可以是Map类型;向Map集合中加入元素时,必须提供一对键对象和值对象,从Map集合中检索元素时,只要给出键对象,就会返回对应的值对象。
Map map=new HashMap();
map.put("1","Monday");
map.put("2","Tuesday");
map.put("3","Wendsday");
map.put("4","Thursday");
System.out.println("Map测试==="+map.get("2"));//=Tuesday
Map集合中的键对象不允许重复,即任意两个键对象通过equals()方法比较的结果都是false,对于值对象则没有惟一性的要求,可以将任意多个键对象映射到同一个值对象上,但是后加入的值将会覆盖先加入的值.
Map有两种比较常用的实现:HashMap和TreeMap。HashMap按照哈希算法来存取键对象有很好的存取性能
map.put("1","Monday");
map.put("2","Tuesday");
map.put("3","Wendsday");
map.put("4","Thursday");
System.out.println("Map测试==="+map.get("2"));//=Tuesday
Map集合中的键对象不允许重复,即任意两个键对象通过equals()方法比较的结果都是false,对于值对象则没有惟一性的要求,可以将任意多个键对象映射到同一个值对象上,但是后加入的值将会覆盖先加入的值.
Map有两种比较常用的实现:HashMap和TreeMap。HashMap按照哈希算法来存取键对象有很好的存取性能
多对一关系中多方的配置
<many-to-one name="customer" column="customer_id" class="pkg.customer"/>
<set
name="order"
cascade="sava-update"
inverse="true">
<key column="customer_id"/>
<one-to-many class="pkg.order"/>
</set>
<many-to-one name="customer" column="customer_id" class="pkg.customer"/>
<set
name="order"
cascade="sava-update"
inverse="true">
<key column="customer_id"/>
<one-to-many class="pkg.order"/>
</set>