《深入浅出hibernate》(4)持久层操作
来源:互联网 发布:c语言能干嘛 编辑:程序博客网 时间:2024/05/01 12:57
1。首先是Session.load/get两种方法,两者都可以根据指定的实体类和ID从数据库中读取记录,并返回与之对应的实体对象,区别在于:
A。如果未能发现符合条件的记录,get返回null,而load会抛出ObjectNotFoundException
B。load可以返回实体的代理实例(延迟加载实体对象时,hibernate3默认是延迟加载),而get永远返回实体对象本身
C。load方法可以充分利用内部缓存和2级缓存,而get方法则仅仅在内部缓存中查找,如果没有发现,就直接越过2级缓存进行SQL查询。
2。Session.find/iterate,两个方法在hibernate3中被Query.list()和Query.iterate方法替代。find的方法将从数据库中获取所有符合条件的记录并构造相应实体对象,实体对象构造完毕后,将之纳入缓存,而iterate是执行N+1查询。另一方面,find方法对缓存只写不读,而iterate方法却可以充分利用缓存,在系统只读或者读取比较频繁的情况下,通过iterate可以获得较大的性能。在进行海量信息查询时,最好结合iterate和evict方法逐条对记录进行处理:
Iterator it = query.iterate();
while (it.hasNext()) {
TUser user = (TUser) it.next();
session.evict(user);
System.out.println("user name:" + user.getName());
}
在实际开发中,对于大批量数据处理,推荐采用SQL或者存储过程。
3。查询缓存,在hibernate.cfg.xml设置:
<property name="hibernate.cache.use_query_cache">true</property>
在每次进行查询前,设置:
query.setCacheable(true);
查询缓存的作用并未像想象中的那么强大,它仅仅在以下情况发挥作用:
A。完全相同的Select SQL重复执行
B。并且在两次查询之间,对应的库表未发生改变
4。接来就是延迟加载的讨论。在hibernate3中延迟加载默认是true,我在javaeye看到帖子说到这个问题:
<many-to-one>默认的属性是lazy="proxy",此时默认是会延迟加载的.在指定了lazy="true"之后,必须要经过运行期字节码增加,延迟加载才有效果.
而<one-to-one>相对要复杂一点,延迟加载还要受到constrained属性的限制.constrained="false"时表明实体和被关联到的实体的约束不是强制的,即存在一个实体时,它通过<one-to-one>关联的实体可能存在,也可能不存在,这时在查询实体时,Hibernate总会发起一次查询检查<one-to-one>所关联的实体是否存在,而这时已经可以把one-to-one关联的实体查询出来了,因此在<one-to-one>关系中,如果constrained="false",总是会立即加载关联到的实体.
如果当constrained="true",且lazy="proxy"(默认),是可以延迟加载的.
如果当constrained="true",且lazy="true"时,需要经过运行期字节码增加,延迟加载才会奏效.
A。实体对象的延迟加载,此时load到的对象其实是实体对象的代理,我在eclipse的debug窗口对load方法设置了断点观察实体对象,确实是一个代理对象,真正的实体的对象位于代理类的target属性,hibernate是通过CGLIB实现对类的代理。
B。集合的延迟加载,需要注意的如果需要在session关闭之后强制加载关联对象,可以通过Hibernate.initialize()方法。另外,关于关联的对象缓存策略,你除了需要设置集合类型的缓存,还需要设置集合所关联对象的实体的缓存策略。
C。属性的延迟加载,除了属性的lazy声明为true外,还需要借助类增强器对class文件进行强化处理,典型的ant配置文件如下:
project name="hibernate3demo" default="instrument" basedir=".">
<property name="lib.dir" value="./lib"/>
<property name="classes.dir" value="./bin"/>
<path id="lib.class.path">
<!-- The object files for this application -->
<pathelement location="${classes.dir}"/>
<!-- The lib files for this application -->
<fileset dir="${lib.dir}">
<include name="*.jar"/>
<include name="*.zip"/>
</fileset>
<!-- All files/jars that Tomcat makes available -->
</path>
<target name="instrument">
<taskdef name="instrument"
classname="org.hibernate.tool.instrument.InstrumentTask">
<classpath path="${classes.dir}"/>
<classpath refid="lib.class.path"/>
</taskdef>
<instrument verbose="true">
<fileset dir="${classes.dir}/com/denny_blue/hibernate3demo/bean">
<include name="TUser.class"/>
</fileset>
</instrument>
</target>
</project>
5。数据的保存。此节主要讨论了save和update方法的执行过程,具体不详述。实际开发中可能更为经常使用SaveOrUpdate()方法
6。数据的批量导入和批量删除。
A。首先是批量导入,没错,迭代调用save方法。如:
for(int i=0;i<100000;i++){
TUser user=new TUser();
user.setName("dennis");
session.save(user);
}
可惜的是当越来越多TUser对象被加入内部缓存时,内存终将耗尽,抛出OutOfMemory异常。如何解决?首先可以设置hibernate.jdbc.batch_size来指定每次提交的SQL数量(注:mysql的驱动不支持此参数),另外,定时清空内存:
for(int i=0;i<100000;i++){
TUser user=new TUser();
user.setName("dennis");
session.save(user);
if(i%25==0){
session.flush();
session.clear();
}
}
B。批量删除:因为ORM需要保持内部缓存和2级缓存中数据与数据库中数据的一致性,所以它需要知道具体删除了哪条数据,也就是说不能仅仅删除数据中的数据。因此hibernate执行批量删除时,会查询出所有符合条件的记录,再对记录进行循环删除。变通方法之一就是提供基于游标的删除操作,如:
ScrollableResults scRes=query.Scroll();
while(scRes.next()){
TUser user=(TUser)scRes.get(0);
session.delete(user);
}
另外,hibernate3提供了批量删除和批量更新的操作,不过,仍然无法保证缓存数据的一致性,也就是在批量更新之后,你加载的很可能是过期实体对象,哪怕是用不同的session加载。
String hql="delete TUser";
Query query=session.createQuery(hql);
int ret=query.executeUpdate();
tx.commit();
- 《深入浅出hibernate》(4)持久层操作
- Hibernate深入浅出(九)持久层操作——数据保存&批量操作
- 《深入浅出Hibernate》读书笔记(5)——持久层操作
- 《深入浅出Hibernate》读书笔记(5)——持久层操作
- Hibernate持久层操作
- Hibernate 持久层操作
- Hibernate学习笔记之持久层操作
- DAO与Factory模式的结合——持久层的设计模式分析(深入浅出Hibernate笔记)
- 持久层理解 hibernate
- Spring+Hibernate操作持久层HibernateTemplate与HibernateTransactionManager
- Hibernate 数据持久层操作类的总结
- MyEclipse开发Hibernate持久层
- Spring持久层(三) Hibernate
- 数据持久层框架Hibernate
- 持久层hibernate创建orm
- Hibernate持久层全面描述
- Hibernate持久层全面描述
- Hibernate持久层全面描述
- 编程实现盗2005 Beta2版QQ
- 母牛生小牛
- 女人和英语
- STL概览-缘起(一)
- C#多线程应用基础
- 《深入浅出hibernate》(4)持久层操作
- STL概览-通用工具pair,auto_ptr,std::rel_ops(二)
- 关于sql在线备份
- IIS支持中文名及中文路径
- 如何从内存中读取受保护的文件?
- 查看SQL 所有表的有关。
- iSee 手机客户端简介
- System.Web.HttpException: 无法在发送 HTTP 标头之后进行重定向的错误??
- 请不要说我在加班