DriverManager всегда возвращает мой пользовательский драйвер независимо от URL-адреса подключения - PullRequest
1 голос
/ 21 апреля 2010

Я пишу драйвер для использования в качестве оболочки для двух отдельных подключений 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;
}

Насколько я понимаю, эта функция acceptSURL будет определять, считает ли 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 предоставляет новые экземпляры моего соединения в качестве совпадений для URL-адресов mysql вместо желаемого драйвера / соединения mysql.

FWIW, я отдельно протестировал реализации, которые идут прямо к драйверу mysql с использованием этого точного синтаксиса (хотя и только по одному), и смог успешно взаимодействовать с каждой базой данных отдельно из тестового приложения вне моего драйвера.

1 Ответ

3 голосов
/ 21 апреля 2010

ИМО, основная проблема с этим кодом в том, что он использует DriverManager. Избегайте статики и придерживайтесь примеров.

Конкретная проблема в том, что DriverManager.getConnection идет непосредственно к попытке connect, а не к acceptsURL, который getDriver делает. Следовательно, ваша реализация connect должна выполнить ту же проверку, что и реализация acceptsURL (она может быть даже более строгой и, возможно, завершится с ошибкой во время выполнения).

Как относительно незначительный момент, реализация acceptsURL немного странна.

if (url.contains("jdbc:jgb://"))
{ return true; }
return false;

contains должно быть startsWith. Маленький танец с if и return s не помогает ясности. Это может быть записано как:

return url.startsWith("jdbc:jgb://");
...