使用不同的 jdbc 驱动程序连接到多个数据库
Posted
技术标签:
【中文标题】使用不同的 jdbc 驱动程序连接到多个数据库【英文标题】:connecting to multiple databases using different jdbc drivers 【发布时间】:2011-06-18 16:28:01 【问题描述】:我需要编写一个基于守护进程的 Java 进程(不是基于 Web),它将连接到 Oracle 10G 数据库,从中读取一些数据,然后连接到 SQL Server 数据库并将数据写入表。
听起来很简单,但我对此有几个疑问。
我需要有两个 jdbc 驱动程序,即一个用于连接到 Oracle 数据库,另一个用于连接到 sql server 数据库。 sql server jdbc 驱动程序是 jtds jdbc 驱动程序 (http://jtds.sourceforge.net/),对于 Oracle,我将使用标准的 oracle jdbc 驱动程序。我是否可能会同时遇到类路径中可用的两个驱动程序的任何问题?
我的猜测是,我只需要一个 ConnectionManager 类来管理连接和一个客户端 DAO 类,它会调用相关方法来获取所需的连接,具体取决于它是从 Oracle 读取还是写入 SQL服务器。这是一种合理的方法还是有更好的设计/模式?
编辑
好的,我尝试了一个快速的设计解决方案。见下图
我认为我遇到的问题是如何提交。下面是处理流程
InvoiceBD 从工厂类获取 Oracle 连接,并调用 InvoiceUploadDAO.readData,将 Oracle 连接对象传递给它。 InvoiceBD 从工厂类获取 SQL Server 连接并调用 InvoiceUploadDAO.writeData,将 SQL Server 连接对象传递给它。 InvoiceBD 重复使用 Oracle 连接将 InvoiceUploadDAO.update 状态调用为 Oracle 数据库上的“完成”设置状态。InvoiceBD 提交 Oracle 连接。 InvoiceBD 提交 SQL Server 连接。
或者如果出现问题,两个连接对象都会回滚。
这听起来对吗?
谢谢
【问题讨论】:
将 2 个 jdbc 驱动程序放在类路径中没有问题。关于设计/模式只需将其构建为您需要的简单/复杂。两个 Connection 变量可能足以满足您的需要。 图像的链接已损坏,至少从 *** 中查看是这样。顺便说一句,你为什么更新这个问题?是验证设计吗? 是的,只是想确保这是正确的做法。图片的直接链接是i279.photobucket.com/albums/kk128/ziggy_76/… 【参考方案1】:我是否可能会同时遇到类路径中可用的两个驱动程序的任何问题?
不太可能。 DriverManager.getConnection
方法实际上将连接的构建委托给所有向它注册的驱动程序。只有识别 JDBC URL 中协议的驱动程序才会返回连接。 JDBC 规范规定:
当
DriverManager
试图 建立连接,它调用 驱动程序的连接方法并通过 驱动 URL。如果Driver
实现理解 URL,它 将返回一个Connection
对象; 否则返回null
。...
JDBC URL 的格式是:
jdbc:<subprotocol>:<subname>
对于 jTDS 和 Oracle(瘦)驱动程序,协议格式不同,因此您永远不会遇到问题。但是,请记住不要放置多个版本的同一驱动程序。
这是一种合理的方法还是有更好的设计/模式?
您正在寻找DataSource
。 DataSources 本来可以在 Java EE 环境中使用,而不是在 Java SE 应用程序中。但是,您可以构建自己的 DataSource 或类似的类;你不需要实现 DataSource 接口本身,但你可以做类似的事情。在您的上下文中,您的 ConnectionManager
类将通过可能接受区分要连接到哪个数据库的参数来承担 DataSource 的角色;您可以考虑使用连接池以备不时之需(如果您只需要一个与数据库的连接,则不太可能)。
您也可以采用@duffymo 的方法来构建 DAO 类,尽管它更适合 SQL 查询不同的情况。
【讨论】:
@ziggy,如果您以相同的方法连接到两个数据库,您很可能需要一个事务协调器和 XAConnections 而不是普通的连接。在您当前的设计中,如果已提交工作,则无法回滚第二个连接可能根本不会影响第一个连接。 如果我只打算在最后提交怎么办。 IE。仅从 InvoiceBD 提交且仅在对两个数据库的写入均已完成的情况下提交? 这就是我所指的过程。整个提交操作不是原子的。如果第一个成功,第二个失败,那么你必须在第一个做清洁工作。这就是为什么要构思跨多个数据源的 XA 事务或全局事务。 我对 XA 事务不是很熟悉。我将不得不阅读。你知道SQL Server (jtds) 和Oracle jdbc driver(ojdbc14) 是否都支持XA 事务。 是的,他们都有。但是您还需要获得一个 Java 事务管理器来执行这两个连接之间的实际协调。【参考方案2】:-
类路径中的两个驱动程序都没有问题。如果您需要将读取和写入作为单个事务,您可能需要考虑同时使用 XA 驱动程序。如果您需要两阶段提交,则需要同时支持这两个阶段的 XA 驱动程序。
您需要两个 DAO 实例,一个用于 Oracle 读取,另一个用于 SQL Server 写入。
【讨论】:
谢谢@duffymo。我不太明白为什么有两个 DAO 实例。不只是 URL 会有所不同吗?我添加了一个包含所有常见 jdbc 方法的 DatabaseImpl,并将特定于数据库的方法放在“*Impl”类中。见上图。以上是关于使用不同的 jdbc 驱动程序连接到多个数据库的主要内容,如果未能解决你的问题,请参考以下文章
如何使用带有 TNSNames 别名语法的 JDBC 瘦驱动程序连接到 Oracle 数据库