我正在编写一个驱动程序,作为两个独立MySQL连接(到分布式数据库)的包装器。基本上,目标是为所有应用程序启用与驱动程序的交互,而不是要求应用程序整理哪个数据库保存所需数据。
大部分代码都已到位,但我遇到的问题是,当我尝试通过MySQL驱动程序创建连接时,DriverManager会返回我的驱动程序实例而不是MySQL驱动程序。我很感激有关可能造成这种情况的任何提示以及可以采取哪些措施来解决这个问题!
以下是一些相关的代码片段。我可以提供更多,但有很多,所以我需要知道你还想看到什么。
首先,来自MyDriver.java:
public MyDriver() throws SQLException
{
DriverManager.registerDriver(this);
}
public Connection connect(String url, Properties info)
throws SQLException
{
try { return new MyConnection(info); }
catch (Exception e) { return null; }
}
public boolean acceptsURL(String url)
throws SQLException
{
if (url.contains("jdbc:jgb://"))
{ return true; }
return false;
}
据我所知,这个acceptedURL函数将决定DriverManager是否认为我的驱动程序适合给定的URL。因此,如果URL包含“jdbc:jgb://”,它应该只从我的驱动程序传递连接吗?
以下是来自MyConnection.java的代码:
Connection c1 = null;
Connection c2 = null;
/**
*Constructors
*/
public DDBSConnection (Properties info)
throws SQLException, Exception
{
info.list(System.out); //included for testing
Class.forName("com.mysql.jdbc.Driver").newInstance();
String url1 = "jdbc:mysql://server1.com/jgb";
String url2 = "jdbc:mysql://server2.com/jgb";
this.c1 = DriverManager.getConnection(
url1, info.getProperty("username"), info.getProperty("password"));
this.c2 = DriverManager.getConnection(
url2, info.getProperty("username"), info.getProperty("password"));
}
这告诉我两件事。首先,info.list()调用确认正在发送正确的用户和密码。其次,因为我们进入一个无限循环,我们看到DriverManager提供了我的连接的新实例,作为mysql URL的匹配而不是所需的mysql驱动程序/连接。
FWIW,我已经单独测试了使用这种确切语法直接访问mysql驱动程序的实现(一次只有一个),并且能够从我的驱动程序之外的测试应用程序中成功地与每个数据库进行交互。
答案 0 :(得分:3)
IMO,此代码的主要问题是它使用DriverManager
。避免静态并坚持实例。
具体问题是DriverManager.getConnection
直接尝试connect
而不是acceptsURL
getDriver
。因此,您connect
实现应该执行与acceptsURL
实现相同的检查(它甚至可能更严格,并且可能在运行时失败)。
作为一个相对较小的点,acceptsURL
实现有点奇怪。
if (url.contains("jdbc:jgb://"))
{ return true; }
return false;
contains
应为startsWith
。 if
和return
的小舞蹈无助于清晰。它可以写成:
return url.startsWith("jdbc:jgb://");