日期:2014-05-16 浏览次数:20401 次
转自:http://publishblog.blogdriver.com/blog/tb.b?diaryID=258124
初步比较三种MSSQL JDBC驱动的不同- -
现在我们所用的O/R Mapping主要是针对SQL Server和微软提供的JDBC驱动,因为开发的时候都是用微软的JDBC驱动测试的,一直使用下来也很正常。虽然网上流传微软的JDBC驱动性能很差,但是这上面的性能差异目前还未构成我们系统的瓶颈;况且我们也试过不同的JDBC驱动,如jTDS、jsqlconnect,但是采用这些驱动后都通不过我们现有系统的测试,最主要的问题在于不能返回生成的主键。
今天我简单的比对了一下MS Driver、JSQL Driver、jTDS Driver三种驱动的性能,后两种相差不大,但微软的JDBC驱动和这两者的确存在着较大差距,想想现在系统的数据量也增长了不少,如果可以稍微调整一下程序优化一部分性能,成本还是可以接受的。
上面三种驱动都是不支持JDBC 3.0的驱动,因此无法用getGeneratedKeys方法返回生成的主键。原来在用MS Driver写的时候,是采用select @@identity的方式返回生成的主键的(其实按理应用select SCOPE_IDENTITY()返回主键,但是在事务未提交之前,MS驱动不支持PreparedStatement用该方法查询回主键),采用JSQL和jTDS的驱动,用该方法返回均为空。换成select SCOPE_IDENTITY(),三种驱动都不能正常工作。
public String getIdentity() {
return "select @@identity";
//按理应用SCOPE_IDENTITY(),但是目前SQL
// JDBC驱动不支持PreparedStatement用该方法返回主键
}
因为简单的研究过一下Hibernate,在Hibernate的配置文件中,对MS Driver是not recommended,jTDS Driver是not supported,而支持JSQL Driver。稍微看了一下它的源码,对于SQL Server的Dialect,它是采用“insertsql + select SCOPE_IDENTITY()”的sql,然后通过executeQuery方式返回主键。
public String appendIdentitySelectToInsert(String insertSQL) {
return insertSQL + " select SCOPE_IDENTITY()";
}
我采用Hibernate的方式试了一下,对于MS和JSQL来说都能正常返回,对于jTDS来说,还是返回不了,抛出返回值不是游标的异常。看来要兼容各种数据库和驱动还真是让人头痛的一件事情,……
最后我调整了一下方法,不是采用executeQuery方式返回主键,而是先execute,然后通过getMoreResults来判断是否拿到主键,再通过getResultSet方法拿到生成的主键,在三种驱动上都测试通过。
总结一下:
? | MS Driver? | jTDS Driver? | JSQL Driver? |
事务内先insert,再通过select @@identity返回主键(分两次执行) | 支持? | 不支持? | 不支持? |
事务内先insert,再通过select SCOPE_IDENTITY()返回主键(分两次执行) | 不支持? | 不支持 | 不支持? |
事务内通过insertsql + select SCOPE_IDENTITY(),用executeQuery返回主键(一次执行) | 支持? | 不支持? | 支持? |
事务内通过insertsql + select SCOPE_IDENTITY(),用execute,再根据getMoreResults和getResultSet返回主键(一次执行) | 支持? | 支持? | 支持? |
自己写的库比用开源的库好的一点就是可以控制整个框架,能根据实际需要做调整。Hibernate对MS Driver和jTDS的评价也是基于其自己的实现来的,这次简单的比较仅仅是比较返回主键上的不同,没有针对其他的数据库和数据库驱动做测试,采用第四种方式是否比第三种方式具有更大的兼容性还有待进一步测试。
- 作者: crmky 2004年07月26日, 星期一 22:19
?