InterBase, SAPDB
>> 我现在开发Hibernate用的就是微软的官方驱动,弄了好久才弄好的,有些小技巧。<<

公布一下你的技巧吧!

呃,robbin这么晚还在啊
说是技巧有点夸张了,一点经验吧
不知道robbin说微软的JDBC与Hibernate不兼容是不是指用Hibernate.cfg.xml配置文件的问题
不敢藏私,把我的配置文件(部分)贴出来分享给大家,希望能有用:

com.microsoft.jdbc.sqlserver.SQLServerDriver
jdbc:microsoft:sqlserver://127.0.0.1;DatabaseName=数据库名;SelectMethod=Cursor
用户
密码
XX
net.sf.hibernate.dialect.SybaseDialect

...

注意,和JSQL的驱动不同的是,要注释掉


这两句,就能连接上了
不过用Hibernate的ddl2hbm工具,我就始终连不上SQL Server,是用Middlegen生成的hbm,但是Middlegen生成的hbm文件的class名、属性名好像都不能超过11个字符,后面的字符都被它吃掉了,谁有遇到这种情况,有没有什么办法解决?

呃,robbin这么晚还在啊
说是技巧有点夸张了,一点经验吧
不知道robbin说微软的JDBC与Hibernate不兼容是不是指用Hibernate.cfg.xml配置文件的问题

不敢藏私,把我的配置文件(部分)贴出来分享给大家,希望能有用:
<session-factory>
<property name="hibernate.connection.driver_class">com.microsoft.jdbc.sqlserver.SQLServerDriver</property>
<property name="hibernate.connection.url">jdbc:microsoft:sqlserver://127.0.0.1;DatabaseName=数据库名;SelectMethod=Cursor</property>
<property name="hibernate.connection.username">用户</property>
<property name="hibernate.connection.password">密码</property>
<property name="hibernate.connection.pool.size">XX</property>
<property name="hibernate.dialect">net.sf.hibernate.dialect.SybaseDialect</property>
<!-- Mapping files -->
...

注意,和JSQL的驱动不同的是,要注释掉

<property name="database.schema" value=""/>
<property name="database.catalog" value=""/>

这两句,就能连接上了
不过用Hibernate的ddl2hbm工具,我就始终连不上SQL Server,是用Middlegen生成的hbm,但是Middlegen生成的hbm文件的class名、属性名好像都不能超过11个字符,后面的字符都被它吃掉了,谁有遇到这种情况,有没有什么办法解决?
我下载了SAPDB7.4 Windows版,使用SAPDB官方JDBC驱动,替换掉MySQL,又测试了一下,更加不解了。

Read 3000 Records
JDBC: 35ms
Hibernate List: 210ms
Hibernate Iterator: 4s
Hibernate Iterator JCS: 50ms

测试结果和MySQL是一样的,不过明显看的出SAPDB的JDBC读速度比MySQL还要快,但是我非常不解的是为什么Hibernate Iterator的读速度如此之慢,它为什么要花那么多时间去遍历结果集呢?而且即使使用了缓冲机制,Hibernate的读速度也没有超过JDBC,在MySQL上同样也是如此。

本来还想测试一下30万的结果集遍历100条记录的,比较一下List和Iterator,结果又出了意外。我使用Hibernate来插入10万条记录,结果DB Instance竟然挂了!!!重起都没有用,必须删除Instance,重新创建。改用JDBC插入10万条记录,花24s顺利完成。我搞不懂同样插入10万条记录,Hibernate是怎么把Instance给挂掉的?

又试了一次,用JDBC插入10万条,24s完成,用Hibernate插入10万条,DB又挂了,然后重新创建,这次试着用JDBC1次插入30万条,DB竟然也挂了!!!

My God,我用Hibernate往MySQL里面插入20万条记录,MySQL也没有挂掉,SAPDB是怎么搞的?还是我的机器的问题,或者我没有把SAPDB配置好吧。不测试了,没有精力再搞了

昨天调程序的时候,就差点让我载在这个SelectMethod=Cursor,因为这不是个默认值,至于兼容不兼容,到现在看还正常。不过也听说Microsoft的JDBC有问题,据说跟其它driver比起来有性能问题。
花了一些时间用SQL Sever试了一下,代码基本就是Robbin的代码,只不过我把driver全换成Microsoft的JDBC Driver了。不过我测试的这些数据也是一些参考数据。

测试环境:
CPU: P3 650
内存:192MB (JVM参数加上 -Xms64m -Xmx64m,太穷了没办法)
硬盘: IBM-DJSA-21010GB 7200转
OS: WindowsXP
数据库: SQL SERVER 2000 中文版
JDBC驱动: 官方驱动程序

Hibernate and JDBC 都没有使用connection pool

测试项目1:插入1000条记录到cat表
Hibernate: 3.01s
JDBC Batch: 2.33s

插入10000条记录到cat表
Hibernate: 20.41s
JDBC Batch: 14.51s

如果用(Hibernate-JDBC Batch)/JDBC Batch 这个公式的话,以上测试的值在30%-40%之间,这和Robbin测的插入数据结果40%左右基本一致。

测试项目2:读11000条记录从cat表
Hibernate List:3.85秒
Hibernate Iterator: 1449秒
JDBC : 2.74秒
这个数据与Robbin相差较大. 不明.

测试项目3:读1000条记录从cat表(表中共有1000条记录),但侧重于setFetchSize对两者的影响.

(1)没有FetchSize时:
Hibernate List:1.19秒
Hibernate Iterator: 21.58秒
JDBC : 0.85s

(2)有FetchSize,值为1500, that is,FetchSize大于记录总数:
Hibernate List:1.19秒
Hibernate Iterator: 21.62秒
JDBC : 0.91s

(2)有FetchSize,值为100, that is,FetchSize小于记录总数:
Hibernate List:1.20秒
Hibernate Iterator: 22.80秒
JDBC : 0.86s

从测试结果看,FetchSize大于记录总数 比 FetchSize小于记录总数, 对Hibernate这边的影响与对JDBC的影响不同. 这在分析,也许是测试的问题吧.

你都有这么多时间做这样的测试
羡慕,真是羡慕

我们整天就是写程序,写设计
真希望啥时候能闲一闲

你的测试数据看起来,JDBC Read和Hibernate List很接近,感觉比较正常,我在MySQL上面测试,总有2倍的差距,不知道为什么。那个Iterator怎么还是那么慢?试试大结果集选取少量数据看看?然后用JCS再看看。

主程序用下面的代码试试,Read连续运行10次,抛弃第1次的结果,后面的结果取平均。

package com.fankai;

public class Main {
public static void main(String[] args) throws Exception {
//TestCatHibernate.testCreate(Integer.parseInt(args[0]));
//TestCat.testCreate(Integer.parseInt(args[0]));
for (int i=0; i< 10; i++) {
//TestCat.testReadAll(Integer.parseInt(args[0]));
TestCatHibernate.testReadAll(Integer.parseInt(args[0]));
}
}
}
下面是我用DB2运行你的程序的测试结果:
[03-8-21 12:19:36:069 CST] 62b40a83 SystemOut O Start Creating Records with Hibernate...
[03-8-21 12:19:36:409 CST] 62b40a83 SystemOut O Finished Creating Records with Hibernate: 340ms
[03-8-21 12:19:36:409 CST] 62b40a83 SystemOut O Start Reading Records with Hibernate...
[03-8-21 12:19:36:419 CST] 62b40a83 SystemOut O Finished Reading Records with Hibernate: 10ms
[03-8-21 12:19:36:419 CST] 62b40a83 SystemOut O Start Creating Records with Hibernate...
[03-8-21 12:19:36:770 CST] 62b40a83 SystemOut O Finished Creating Records with Hibernate: 351ms
[03-8-21 12:19:36:780 CST] 62b40a83 SystemOut O Start Reading Records with Hibernate...
[03-8-21 12:19:36:790 CST] 62b40a83 SystemOut O Finished Reading Records with Hibernate: 10ms
[03-8-21 12:19:36:790 CST] 62b40a83 SystemOut O Start Creating Records with Hibernate...
[03-8-21 12:19:37:190 CST] 62b40a83 SystemOut O Finished Creating Records with Hibernate: 400ms
[03-8-21 12:19:37:190 CST] 62b40a83 SystemOut O Start Reading Records with Hibernate...
[03-8-21 12:19:37:200 CST] 62b40a83 SystemOut O Finished Reading Records with Hibernate: 10ms
[03-8-21 12:19:37:200 CST] 62b40a83 SystemOut O Start Creating Records with Hibernate...
[03-8-21 12:19:37:601 CST] 62b40a83 SystemOut O Finished Creating Records with Hibernate: 390ms
[03-8-21 12:19:37:601 CST] 62b40a83 SystemOut O Start Reading Records with Hibernate...
[03-8-21 12:19:37:611 CST] 62b40a83 SystemOut O Finished Reading Records with Hibernate: 10ms
[03-8-21 12:19:37:621 CST] 62b40a83 SystemOut O Start Creating Records with Hibernate...
[03-8-21 12:19:37:942 CST] 62b40a83 SystemOut O Finished Creating Records with Hibernate: 321ms
[03-8-21 12:19:37:942 CST] 62b40a83 SystemOut O Start Reading Records with Hibernate...
[03-8-21 12:19:37:952 CST] 62b40a83 SystemOut O Finished Reading Records with Hibernate: 10ms
[03-8-21 12:19:37:952 CST] 62b40a83 SystemOut O Start Creating Records with Hibernate...
[03-8-21 12:19:38:392 CST] 62b40a83 SystemOut O Finished Creating Records with Hibernate: 440ms
[03-8-21 12:19:38:392 CST] 62b40a83 SystemOut O Start Reading Records with Hibernate...
[03-8-21 12:19:38:402 CST] 62b40a83 SystemOut O Finished Reading Records with Hibernate: 0ms
[03-8-21 12:19:38:412 CST] 62b40a83 SystemOut O Start Creating Records with Hibernate...
[03-8-21 12:19:38:863 CST] 62b40a83 SystemOut O Finished Creating Records with Hibernate: 451ms
[03-8-21 12:19:38:863 CST] 62b40a83 SystemOut O Start Reading Records with Hibernate...
[03-8-21 12:19:38:873 CST] 62b40a83 SystemOut O Finished Reading Records with Hibernate: 10ms


不过我改了一下你的cat.hbm.xml,你原来写的是:
<id name="id" unsaved-value="null">
<generator class="uuid.hex"/>
</id>
我改为:
<id name="id" type="string" unsaved-value="null" >
<column name="CAT_ID" sql-type="char(32)" not-null="true"/>
<generator class="uuid.hex"/>
</id>
因为按照你那样的写法,在我这里运行,报告错误:
ERROR com.fankai.TestCatHibernate: -> Could not execute query: [IBM][CLI Driver][DB2/NT] SQL0206N "CAT0_.ID" 在使用它的上下文中无效。 SQLSTATE=42703
还有,我测试用的循环是:


for (int i=0; i< 100; i++) {
//TestCat.testReadAll(Integer.parseInt(args[0]));
TestCatHibernate.testCreate(100);
TestCatHibernate.testReadAll(100);
}
我今天花了1个小时时间安装上了Oracle817,精简安装。这次在Oracle上测试了1下,终于有了点眉目了!

测试环境:基本环境同上
数据库:Oracle8.1.7.0.0 for WindowsNT
JDBC驱动:ojdbc14.jar ( 最新的 for JDK1.4的驱动)
JDK: J2SDK1.4.2

插入数据:1000条
JDBC Batch: 530ms
Hibernate: 1052ms

最有趣的是Read测试,由于Oracle的JDBC驱动对FetchSize有良好的支持,设置不同的FetchSize,对测试结果有明显的影响!

读取3000条记录,分别设置不同的FetchSize,JDBC测试用例是在程序中设置:pstmt.setFetchSize(100);而Hibernate是在配置文件中设置:hibernate.jdbc.fetch_size 100,如果都不设置FetchSize的话,那么将取JDBC驱动的默认值,Oracle的默认值是10。


测试1:FetchSize=10 (Oracle默认值)
JDBC: 220ms
Hibernate List: 700ms
Hibernate Iterator: 4998ms
Hibernate Iterator JCS: 200ms

Hibernate的读取速度和JDBC有较大的差距,但是使用JCS以后,速度首次超过JDBC。


测试2 Fetch Size = 100
JDBC: 100ms
Hibernate List: 340ms
Hibernate Iterator: 4927ms
Hibernate Iterator JCS: 70ms

扩大Fetch Size以后,所有的程序读取速度都有了非常明显的加快,但是它们加快的速率是不一样的。

测试3 Fetch Size = 500
JDBC: 110ms
Hibernate List: 310ms
Hibernate Iterator: 5608ms
Hibernate Iterator JCS: 70ms

对于JDBC和Hibernate Iterator来说,似乎已经到了速度增加的临界值,速度不但没有加快,反而开始下降,但是Hibernate List继续加快。

测试4 Fetch Size = 1000
JDBC: 130ms
Hibernate List: 280ms
Hibernate Iterator: 4998ms
Hibernate Iterator JCS: 70ms

测试结果同上,更加明显看出JDBC和Hibernate Iterator超过临界值,速度下降更多,不过使用JCS以后,是从JCS缓冲区取数据,不受FetchSize的影响,因此Hibernate Iterator JCS并没有什么变化,但是Hibernate List继续加快。

测试5 Fetch Size = 2000
JDBC: 140ms
Hibernate List: 300ms
Hibernate Iterator: 7481ms
Hibernate Iterator JCS: 80ms

Hibernate List似乎也到达临界值,所有的测试速度都开始下降。

测试6 Fetch Size = 3000
JDBC: 180ms
Hibernate List: 310ms
Hibernate Iterator: 8713ms
Hibernate Iterator JCS: 90ms

明显超过临界值,速度开始明显下降。

从上面的测试结果,大概可以看出一点眉目来:

一、Fetch Size的选取对读取速度有很大影响,对于不同的结果集应该都有一个临界值,是读取速度最快的Fetch Size。不过似乎Fetch Size的临界值远小于结果集大小。

二、JDBC和Hibernate Iterator的速度变化同步,这似乎在说明,JDBC读取数据的方式是每次从数据库中读Fetch Size大小的数据,而Iterator似乎是对JDBC ResultSet的封装,但是为什么会更慢?

三、Hibernate List速度变化和JDBC不同步,List似乎总是把结果集1次取出来,所以FetchSize越大速度越快。

四、Hibernate Iterator JCS是从缓冲区取数据,不受Fetch Size的影响,在所有的测试中,速度都是最快的。

五、 JDBC的速度临界值在100左右,而Hibernate List速度临界值在1000左右。默认的Fetch Size是10,看起来明显有点保守,也许比较适合小结果集的情况。

uu_snow,
最好一个一个来,别把插入和查询写在一起,另外我觉得测试应该有比较,你这样全用Hibernate,看不出效果呀。

我第二次在主程序加入10次Loop, 在hbm.xml中加入JCS


<class name="com.fankai.Cat" table="cat">
<jcs-cache usage="read-only" />
<id name="id" unsaved-value="null">
<generator class="uuid.hex"/>
</id>
。。。。

把所有的FetchSize 注释掉,测试结果如下:
表中有2000条记录,只查询头2条。 太多数据我机子太慢了。

JDBC 我用select top 2 * from cat
Hibernate 我用q.setFirstResult(2);

以下为去掉第一次后的,取后面的均值
JDBC: 0.03 秒

有JCS
Hibernate list: 1.83 秒
Hibernate Iterator: 42.32 秒

无JCS
Hibernate list: 1.81 秒
Hibernate Iterator: 42.44 秒

从测试的数据上看,JCS对Hibernate list没有什么影响,不过对Iterator影响也不是很大。不知微软的Driver怎么转的。

难道是我的JCS用的不对?
Robbin, 我是不是还配置cache.ccf文件?我想Hibernate应有默认值吧.