再谈ADO .NET vs JDBC
曾经在.NET下有过大约三年的开发经历,可以说非常熟悉ADO .NET。ADO .NET最大的特性是对断开连接方式的全方位支持,其引入了DataSet、DataTable、DataRow等等对象,构建了一个“内存数据库”简化版本,DataAdapter把DataReader的数据填充到DataTable或者DataSet中,给使用者一个直观的使用方式。ADO .NET还能够和ASP .NET和Windows Form的控件进行数据邦定,使得编写一些小程序很简单。
刚开始转向Java平台进行开发时,发现JDBC没有这些特性,一下子没习惯过来,觉得JDBC很难用,一些习惯于ADO .NET的同事,还打算自行开发一套类似DataSet、DataTable的咚咚。
在Java平台下开发应用,已经一年多了,这一年中,对JDBC的看法慢慢有了一些变化,也同时反过来思考ADO .NET,发现了JDBC的很多优点,也发现了ADO .NET的一些缺陷。今天我粗略阅读了一遍JDBC 3.0的规范后,把一些想法整理如下:
1、ADO .NET最大的优点是对断开连接访问数据库方式的强有力支持。相比起来,JDBC也引入类似的功能,RowSet,但是比起ADO .NET来,还是不够。
2、ADO .NET功能不完整。MS对这一点也是承认的,承认ADO .NET不能替代ADO。其中一个很重要的功能是分页访问数据的支持。以前在开发ADO .NET程序时,还专门编写一个程序,调用ADO,分页获取数据。
3、ADO .NET的一些接口设计不恰当:
a、对接口编程支持不好。特别在.NET Framework 1.0中,问题特别严重。例如你想基于接口编程,编写如下的代码:
IDbCommand command = conn.CreateCommand();
IDataAdapter dataAdapter = ; //这个又如何构建呢?
在.NET Framework 2.0中,情况有所改善,可以这样写:
IDbConnection connection = provider.CreateConnection ();
IDataAdapter adapter = provider.CreateDataAdapter ();
在.NET Framework 1.x中,ADO .NET肯定没有认真考虑基于接口编程,而JDBC最初设计时,就是完全基于接口编程。.NET Framework 2.0中,Microsoft意识了其这个短视的行为,增加了DbProiderFactory的接口,但是我觉得还是不如JDBC作得好。
在JDBC中,你可以这样写:
String userName = "sa";
String password = "";
Connection conn = DriverManager.getConnection(url, userName, password);
JDBC中,与ADO的ConnectionString是URL,JDBC Driver的URL格式为:
jdbc:<subprotocol>:<subname>
不同的Driver实现,认识不同的subprotocol。你可以在动态装载一个Driver,例如:
而不同的Driver通过实现acceptsURL来识别自己的subprotocol。例如一个Driver的实现:
if (url != null && url.startsWith("jdbc:ksql:")) {
return true;
}
return false;
}
3、JDBC的数据源的获取方式多样:
a、直接通过DriverManager.getConnection获得连接
b、通过应用服务器的数据源获得连接。例如:
Context ctx = new InitialContext();
// Get the DataSource object associated with the logical name
// "jdbc/AcmeDB" and use it to obtain a database connection
DataSource ds = (DataSource)ctx.lookup("jdbc/AcmeDB");
Connection con = ds.getConnection("user", "pwd");
.NET中,没有类似的咚咚。
4、ADO .NET不包括分布式事务的接口,ADO .NET的分布式事务是通过MS DTC统一管理的。JDBC本身就提供了对分布式事务支持的接口,不同的JDBC Driver实现了这一个接口,就支持分布式事务了。
5、ADO .NET中,不同的ADO .NET Provider的参数格式不一样的。OleDb和Odbc都是使用匿名参数,SqlClient使用“@”开头的命名参数,OracleCLient使用“:”开头的命名参数。这明显让人无法基于接口编程嘛,以前使用ADO .NET时,为了基于接口编程,必须自己编写一大堆工具类,很讨厌!
6、JDBC的一些类层级结构不合理。其中一个明显的就是Statement、PreparedStatement、CallableStatement继承关系不合理。ADO .NET没有此问题
7、JDBC中,参数计数是从1开始的,最初使用者容易犯错。ADO .NET没有此问题
JDBC是一个规范,是一个标准,而ADO .NET只是微软的私家类库。.NET Framework目前成为标准的类库还只有一小部分,.NET走向开放的道路的路途漫漫啊!MONO的ADO .NET实现,不知道是否对Microsoft构成了侵权行为?
总结
a、JDBC开放,框架设计良好,但在一些细节地方有些小瑕疵。
b、ADO .NET易用性好,对断开连接式的数据访问支持很好,但整体设计和开放性稍差。