Hibernate入门(杂篇)
hibernate.jdbc.fetch_size50
hibernate.jdbc.batch_size25
这两项会影响到Hibernate的CRUD性能!
C=create,R=read,U=update,D=delete
Fetchsize是指JDBC的statement读取数据库的时候每次从数据库中取出的记录数
例如一次查询1万条记录,对于Oracle的JDBC的驱动来说的话是不会1次性把1万条数据都直接取出来,而只会读取FetchSize条数,当记录集遍历完了这些记录以后,再去数据库取FetchSize条数据!
因些会大大减少内存的使用次数节省内存消耗.FetchSize的数值设置的越大,读取数据库的次数就会越少,速度也就越快;...(相反)
Oracle数据库的JDBC驱动默认的FetchSize=10,是一个非常保守的设定,根据我的测试,当FetchSize=50的时候,性能会提升1倍之多,当FetchSize=100,性能还能继续提升20%,FetchSize继续增大,性能提升的就不显著了。(转载自“中文JAVA技术网”)
因此我建议使用Oracle的一定要将FetchSize设到50。。(转载自“中文JAVA技术网”)
不过并不是所有的数据库都支持FetchSize特性,例如MySQL就不支持。
MySQL就像我上面说的那种最坏的情况,他总是一下就把1万条记录完全取出来,内存消耗会非常非常惊人!这个情况就没有什么好办法了
BatchSize是设定对数据库进行批量删除,批量更新和批量插入的时候的批次大小,有点相当于设置Buffer缓冲区大小的意思。
BatchSize越大,批量操作的向数据库发送sql的次数越少,速度就越快。我做的一个测试结果是当BatchSize=0的时候,使用Hibernate对Oracle数据库删除1万条记录需要25秒,BatchSize=50的时候,删除仅仅需要5秒!!!
可见有多么大的性能提升!很多人做Hibernate和JDBC的插入性能测试会奇怪的发现Hibernate速度至少是JDBC的两倍,就是因为Hibernate使用了BatchInsert,而他们写的JDBC没有使用Batch的缘故。
以我的经验来看,Oracle数据库BatchSize=30的时候比较合适,50也不错,性能会继续提升,50以上,性能提升的非常微弱,反而消耗内存更加多,就没有必要了
拿Hibernate中的get()和load()方法来说当返回数据为空时get()将返回NULL而load()将抛出ObjectNotFoundException这里我们针对load进行解释
示例:
Studentstu=(Student)session.load(Student.class,"1001");【1001:为ID】
load()方法主要返回的是一个Hibernate的代理类不会直接去调用数据库/相反get()永远不会返回代理类它会始终访问数据库【其实用load()的一个好处就在于如果我有一个coment:comment.setClaszB(B);当comment保存的时候你只需要B的主键;而恰恰代理类只返回对象的ID】这个代理类只不过是提供了一个查询数据库的一个能力;当我们调用session.load()方法时只不过返回了一个Hibernate生成代理类(怎么生成稍后做解释)这里面并没有我们想要的数据;在session关闭的时候调用stu.getName()方法就会抛出org.hibernate.LazyInitializationException:couldnotinitializeproxy-noSession异常像我们前面所说的这个代理类有一查询数据库的能力,示例中的session.load()方法前面加了一个(Session)强制转换更能说明代理的是Student的子类也就是说具有更强的功能(查询数据库的能力);在session没有关闭的时候我们调用stu.getName()方法就会返回我们需要的数据,这时在关闭session的情况下我们在调用Student这个类的时候就不会有异常了...可能有人会想如果我只是想让借这个代理类去查询数据库感觉有点多余!如果只是这样想我们完全可以用Hibernate.initialize(str)来初始化这个代理对象【详细请看http://mllongze.iteye.com/blog/907968】
这个代理类其实是靠HibernateJAR包里的asm.jar和cglib-2.1.3.jar在内存中修改Student类的字节码修改后的字李码只要是符合class文件的规则就可以创建出代理对象了;