JDBC пример

В примере рассматривается взаимодействие сразу с несколькими СУБД (oracle, ms sql, postgresql, mysql, derby) по подключению к серверу, созданию и удалению схемы (базы данных), созданию и удалению таблицы. При небольшой доработке можно одновременно работать сразу с несколькими разнотипными реляционными СУБД. Пример создан с использованием всех основных принципов объектно-ориентированного программирования - инкапсуляция-наследование-полиморфизм.

Описание примера

Рассматриваемый JDBC пример включает несколько файлов java, реализующих принципы ООП :

  • dao_base.java - базовый класс определения свойств и функций доступа к серверу БД;
  • dao_oracle.java, dao_mssql.java, dao_postgres.java, dao_mysql.java, dao_derby.java - классы, наследующие свойства базового класса и реализующие функции доступа к конкретному серверу БД;
  • test_jdbc.java - модуль тестирования.

Дополнительно пример включает СУБД Apache Derby, которая наряду с драйверами JDBC включена в исходный код примера. СУБД Derby работает в режиме "EmbeddedDriver", т.е. запускается под управлением виртуальной машины JVM вместе с примером. Пример можно использовать для разработки и отладки дополнительных функций. Исходный код примера в виде проекта Eclipse можно скачать здесь.

Базовый класс, dao_base.java

/**
 * Базовый класс модуля доступа DAO к объектам БД
 */
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;

public abstract class dao_base {
    protected  String      driver     = null;  // драйвер JDBC
    protected  String      url        = null;  // строка подключения
	
    protected  Properties  properties = null;  // свойства подключения объекта Connection
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    public dao_base(String driver) {
        this.driver = driver;
    }
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    /**
     * Процедура регистрации драйвера JDBC
     */
    protected void RegisterDriverManager() {
        try {
            Class.forName(driver).newInstance();
        } catch (InstantiationException e) {e.printStackTrace();
        } catch (IllegalAccessException e) {e.printStackTrace();
        } catch (ClassNotFoundException e) {e.printStackTrace();}
    }
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    /**
     * Процедура определения строки подключения URL к серверу БД
     * @param host - имя компьютера
     * @param database - наименование БД (может быть пустой строкой)
     * @param port - порт сервера
     */
    public abstract void setURL (String host, String database, int port);
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    /**
     * Функция получения объекта подключения
     * @return Connection - объект подключения
     */
    public abstract Connection getConnection ();
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    /**
     * Процедура регистрации драйвера подключения к серверу СУБД JDBC и определения свойств
     * @param login - логин подключения
     * @param password - пароль подключения
     */
    public void Connect (String login, String password) {
        // Регистрация драйвера
        RegisterDriverManager();

        // Определение свойств подключения Connection
        properties = new Properties();
        properties.setProperty("password"         , password);
        properties.setProperty("user"             , login   );
        properties.setProperty("useUnicode"       , "true"  );
        properties.setProperty("characterEncoding", "utf8"  );
    }
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    /**
     * Процедура отключения от сервера БД
     * @param connection объект подключения
     */
    public void Disconnect (Connection connection) {
        try {
            connection.close();
            connection = null;
        } catch (SQLException e) {}
    };
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    /**
    * Функция создания схемы
     * @param schema наименование схемы
     * @return результат транзакции
     */
    public boolean createSchema(final String schema) {
        return false; 
    }
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    /**
     * Функция удаления схемы
     * @param schema наименование схемы
     * @return результат транзакции
     */
    public boolean dropSchema(final String schema) {
        return false; 
    }
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    /**
     * Функция выполнения SQL-запроса
     * @param sql текст запроса
     * @return результат выполнения запроса
     */
    public boolean execSQL (final String sql) {
        boolean result = false;
        try {
            if (getConnection() != null) {
                Statement statement = getConnection().createStatement();
                statement.execute(sql);
                statement.close();
                statement = null;
                result = true;
            }
        } catch (SQLException e) {
            System.err.println ("SQLException : code = " + String.valueOf(e.getErrorCode()) + 
                                                       " - " + e.getMessage());
            System.err.println ("\tSQL : " + sql);
	        
        }
        return result;
    }
}

Базовый класс является абстрактным, включающим два абстрактных метода setURL() и getConnection(). Данные методы, определяющие строку подключения URL к серверу БД и возвращающие объект подключения Connection к серверу СУБД, должны быть реализованы в "наследниках".

Метод RegisterDriverManager() подключает соответствующий JDBC драйвер к программе. Строка описания драйвера "driver" определяется в конструкторе. Подробнее о выборе и подключении драйвера JDBC можно познакомиться на странице "Класс DriverManager".

Метод Connect() регистрирует драйвер JDBC и определяет свойства подключения.

В связи с тем, что синтаксис создания схемы базы данных CREATE SCHEMA (и удаления "DROP SCHEMA") разных СУБД имеет отличия, то в базовом классе определены методы createSchema(final String schema) и dropSchema(final String schema), которые должны быть переопределены в наследующих классах.

Метод execSQL(final String sql) используется для выполнения СУБД транзакций. В случае возникновения ошибки транзакции в консоль выводится код и сообщение об ошибке.

Модули доступа к СУБД

Модули доступа к серверам СУБД наследуют свойства базового класса и реализуют его функции.

Исходный код dao_oracle.java

/**
 * Модуль доступа к серверу СУБД Oracle 
 */
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

import oracle.jdbc.OracleConnection;

public class dao_oracle extends dao_base
{
    private  OracleConnection  connection = null;
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    public dao_oracle() {
        super ("oracle.jdbc.OracleDriver");
    };
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    @Override
    public void setURL (String host, String service, int port) {
        this.url = String.format("jdbc:oracle:thin:@%s:%d:%s", host, port, service);
    };
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    @Override
    public Connection getConnection () {
        return (java.sql.Connection) connection;
    }
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    @Override
    public void Connect (String login, String password) {
        super.Connect(login, password);
        try {
            connection = (OracleConnection) DriverManager.getConnection(url, properties);
        } catch (SQLException e) {
            connection = null;
        }
    };
}

При создании объекта в родительский конструктор передается описание драйвера. Метод setURL() определяет строку подключения к серверу СУБД. Объект подключения connection создается из родного для драйвера класса - для Oracle это OracleConnection.

В связи с тем, что в Oracle схема связана, как правило, с учетной записью пользователя и создается, "можно сказать", при создании пользователя (при создании пользователем первого объекта), то в модуле dao_oracle функции создания и удаления схемы не переопределены.

Исходный код dao_mssql.java

/**
 * Модуль доступа к серверу СУБД MS SQL Server 
 */

import java.sql.SQLException;
import java.sql.DriverManager;

import java.sql.Connection;

import com.microsoft.sqlserver.jdbc.SQLServerConnection;

public class dao_mssql extends dao_base
{
    private  SQLServerConnection  connection  = null;

    private  final  String   DATABASE_CREATE = "CREATE DATABASE %s ";
    private  final  String   DROP_DATABASE   = "DROP DATABASE %s"   ;
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    public dao_mssql(){
        super ("com.microsoft.sqlserver.jdbc.SQLServerDriver");
    };
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    @Override
    public void setURL (String host, String database, int port) {
        if (database.length() > 0)
            this.url = String.format("jdbc:sqlserver://%s:%d;databaseName=%s;", host, port, database);
        else
            this.url = String.format("jdbc:sqlserver://%s:%d;", host, port);;
    };
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    @Override
    public Connection getConnection (){
        return (java.sql.Connection) connection;
    }
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    @Override
    public void Connect (String login, String password) {
        super.Connect (login, password);
        try {
            connection = (SQLServerConnection) DriverManager.getConnection(this.url, properties);
        } catch (SQLException e) {
            connection = null;
        }		
    };
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    @Override
    public boolean createSchema(final String schema) {
        return execSQL (String.format(DATABASE_CREATE, schema)); 
    }
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    @Override
    public boolean dropSchema(final String schema) {
        return execSQL (String.format(DROP_DATABASE, schema)); 
    }
}

В конструкторе класса определена строка описания драйвера. Формат строки подключения URL к серверу БД MS SQL представлен в методе setURL(String host, String database, int port). Если наименование базы данных "database" определить, то подключение будет выполнено к непосредственной базе данных, в противном случае к серверу.

Исходный код dao_postgres.java

/**
 * Модуль доступа к серверу СУБД PostgreSQL 
 */

import java.sql.Connection;

import java.sql.DriverManager;
import java.sql.SQLException;

import org.postgresql.PGConnection;

public class dao_postgres extends dao_base
{
    private  PGConnection  connection = null;

    private  final  String  SCHEMA_CREATE = "CREATE SCHEMA \"%s\"";
    private  final  String  DROP_SCHEMA   = "DROP SCHEMA \"%s\""  ;
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    public dao_postgres() {
        super ("org.postgresql.Driver");
    };
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    @Override
    public void setURL (String host, String database, int port) {
        if (database.length() > 0)
            this.url = "jdbc:postgresql://" + host + ":" + port + "/" + database;
        else
            this.url = "jdbc:postgresql://" + host + ":" + port;
    };
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    @Override
    public Connection getConnection () {
		return (java.sql.Connection) connection;
    }
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    @Override
    public void Connect (String login, String password) {
        super.Connect(login, password);
        try {
            connection = (PGConnection) DriverManager.getConnection(url, properties);
        } catch (SQLException e) {
            connection = null;
        }
    };
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    @Override
    public boolean createSchema(final String schema) {
        return execSQL (String.format(SCHEMA_CREATE, schema)); 
	}
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    @Override
    public boolean dropSchema(final String schema) {
        return execSQL (String.format(DROP_SCHEMA, schema)); 
    }
}

PostgreSQL в отличие от остальных реляционных СУБД позволяет создавать несколько баз данных "DATABASE", которые являются контейнерами схем "SCHEMA". База данных "postgres" создается по умолчанию. В нашем модуле доступа мы не рассматриваем вопрос создания базы данных, который практически ничем не отличается от создания схемы. По умолчанию мы будем подключаться к БД "postgres", внутри которой будем создавать схему.

Исходный код dao_mysql.java

/**
 * Модуль доступа к серверу СУБД MySQL 
 */
import java.sql.DriverManager;
import java.sql.SQLException;

import com.mysql.jdbc.Connection;

public class dao_mysql extends dao_base
{
    private  com.mysql.jdbc.Connection  connection = null;

    private  final  String DATABASE_CREATE = "CREATE DATABASE IF NOT EXISTS %s " +
                                             "CHARACTER SET utf8 "               +
                                             "COLLATE utf8_general_ci "          ;
    private  final  String DROP_DATABASE   = "DROP DATABASE %s"                  ;
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    public dao_mysql() {
        super ("com.mysql.jdbc.Driver");
    };
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    @Override
    public void setURL (String host, String database, int port) {
        if (database.length() > 0)
            this.url = "jdbc:mysql://" + host + ":" + port + "/" + database;
        else
            this.url = "jdbc:mysql://" + host + ":" + port;
    };
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    @Override
    public Connection getConnection () {
        return connection;
    }
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    @Override
    public void Connect (String login, String password) {
        super.Connect(login, password);
        try {
            connection = (com.mysql.jdbc.Connection) DriverManager.getConnection(url, properties);
        } catch (SQLException e) {
            connection = null;
        }
    };
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    @Override
    public boolean createSchema(final String schema) {
        return execSQL (String.format(DATABASE_CREATE, schema)); 
    }
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    @Override
    public boolean dropSchema(final String schema) {
        return execSQL (String.format(DROP_DATABASE, schema)); 
    }
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
}

В СУБД MySQL понятия базы данных "DATABASE" и схемы "SCHEMA" можно сказать являются синонимами. Поэтому в синтаксисе создания базы данных можно использовать как "CREATE DATABASE database_name", так и "CREATE SCHEMA schema_name".

Исходный код dao_derby.java

/**
 * Модуль доступа к серверу СУБД Apache Derby 
 */
import java.io.File;

import java.sql.Connection;
import java.sql.SQLException;
import java.sql.DriverManager;

public class dao_derby extends dao_base
{
    private  Connection  connection = null;
	
    private  final  String  SCHEMA_CREATE = "CREATE SCHEMA %s";	
    private  final  String  SCHEMA_DROP   = "DROP SCHEMA %s RESTRICT";	
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    public dao_derby()
    {
        super ("org.apache.derby.jdbc.EmbeddedDriver");
    };
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    @Override
    public void setURL (String host, String database, int port) {
        if (database.length() > 0) {
            File file = new File(database);
            this.url = "jdbc:derby:" + file.getAbsolutePath();
        }
    };
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    @Override
    public Connection getConnection () {
        return connection;
    }
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    @Override
    public void Connect (String login, String password) {
        super.Connect(login, password);
        try {
            connection = (Connection) DriverManager.getConnection(url, properties);
        } catch (SQLException e) {
            connection = null;
        }
    };
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    @Override
    public boolean createSchema(final String schema) {
        return execSQL (String.format(SCHEMA_CREATE, schema)); 
    }
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    @Override
    public boolean dropSchema(final String schema) {
        return execSQL (String.format(SCHEMA_DROP, schema)); 
    }
}

Отличительная особенность СУБД Derby в режиме "EmbeddedDriver" заключается в том, что она работает под управлением виртуальной машины JVM вместе с примером. Для доступа к этой СУБД в "dao_derby" необходимо в строке подключения определить путь к БД. В нашем примере она располагается вместе с приложением.

Тестирование JDBC модулей доступа к СУБД

Для тестирования модулей доступа к серверам СУБД конечно необходимо использовать JUnit тесты. Но это не так наглядно. Использование JUnit при разработке приложения представлено на странице Тестирование программы, JUnit. В исходные коды примера в качестве образца включен тест подключения к серверу БД Apache Derby. Данная СУБД выбрана в качестве примера, поскольку управляется той же JVM, что и приложение и не требует дополнительной установки сервера СУБД.

В модуле тестирования "test_jdbc.java" определим массив параметров подключения к серверу СУБД :

-- Идентификаторы параметров подключения 
private  final  int  HOST      = 0;   //  хост  (компьютер)
private  final  int  SCHEMA    = 1;   //  схема (база данных)
private  final  int  LOGIN     = 2;   //  логин подключения
private  final  int  PWD       = 3;   //  пароль подключения
private  final  int  DBMS      = 4;   //  СУБД
private  final  int  ACTIVE    = 5;   //  флаг активности
-- Параметры подключения 
private  String[][]  params    = 
   {{"localhost"            , ""  , "login", "password", "MySQL"   , "true"},  // mysql 
    {"localhost\\SQLEXPRESS", ""  , "login", "password", "MS SQL"  , "true"},  // mssql
    {"127.0.0.1"            , ""  , "login", "password", "Postgres", "true"},  // postgres
    {"localhost"            , "XE", "login", "password", "Oracle"  , "true"},  // oracle
    {""                     , "db", ""     , ""        , "Derby"   , "true"}}; // derby
-- Порты серверов СУБД 
private  final  int [] ports    = {3306, 1433, 5432, 1521, 0};                 // порты СУБД

-- Идентификатор СУБД
private  final  int  idx_mssql    = 1;
private  final  int  idx_postgres = 2;
private  final  int  idx_oracle   = 3;
private  final  int  idx_derby    = 4;

Параметры подключения "params" нужно настроить. Для этого необходимо в первом поле указать HOST сервера СУБД. Для MSSQL неоходимо наряду с хостом указать соответствующий сервис сервера СУБД. Во второй колонке необходимо только подкорректировать SID сервера Oracle. В тестовом примере указывается SID сервера разработчика "XE". Для Derby указан относительный путь к БД. В следующих 2-х колонках необходимо привести соответствующие значения логина и пароля. В последней колонке указывается значение флага активности ACTIVE, который позволяет исключить сервер из тестирования. Данные параметры подключения используются в процедуре подключения createConnecion, которой необходимо передать модуль доступа и идентификатор СУБД :

/**
 * Поцедура подключения к серверу БД
 * @param dao модуль доступа
 * @param idx идентификатор сервера СУБД
 */
private void createConnecion (dao_base dm, final int idx) {
    // Формирование строки подключения
    dao.setURL(params[idx][HOST], params[idx][SCHEMA], ports[idx]);
    // Подключение к серверу
    dao.Connect(params[idx][LOGIN], params[idx][PWD]);
}

Дополнительно определяем флаги создания объектов (схемы, таблицы) и текстовые константы, которые используются при выводе сообщений.

// Флаги создания схемы и таблицы	
private  boolean schema_created = false;
private  boolean table_created  = false;

// Наименование схемы
private  final  String SCHEMA_NAME = "MEDIA"                  ;

// Строковые переменные для вывода сообщений в консоль
private  final  String OBJ_SCHEMA  = "Schema 'MEDIA'"         ;
private  final  String OBJ_TABLE   = "Table 'USERS'"          ;

private  final  String OBJ_CREATED = "\t%s created"           ;
private  final  String OBJ_DROPED  = "\t%s deleted"           ;
private  final  String OBJ_NOT_CR  = "\t%s not created"       ;
private  final  String OBJ_NOT_DEL = "\t%s not created"       ;

private  final  String SUCCESS     = "%s connection : success";
private  final  String FAILED      = "%s connection : failed" ;

SQL-скрипты создания и удаления таблицы :

// Скрипты удаления и создания таблицы пользователей USERS
private  final  String TABLE_DROP   = "DROP TABLE %sUSERS"                ;
private  final  String TABLE_CREATE = "CREATE TABLE %sUSERS( "            +
                                          "id    INT PRIMARY KEY, "       +
                                          "name  VARCHAR(128) NOT NULL, " +
                                          "data  TIMESTAMP )" ;

В SQL-скриптах присутствуют символы '%s', которые должны быть заменены либо на наименование схемы, либо на пустой символ.

Процедура создания схемы и таблицы createObjects

В процедуре "createObjects" схема создается во всех СУБД за исключением Oracle.

/**
 * Процедура создания объектов СУБД
 * @param dao модуль доступа к СУБД
 * @param idx идентификатор СУБД
 */
private void createObjects(dao_base dao, final int idx)
{
    // Создание схемы
    if (idx != idx_oracle) {
        // Создание схемы
        schema_created = dao.createSchema(SCHEMA_NAME);
        if (schema_created) {
            // Schema created
            System.out.println (String.format(OBJ_CREATED, OBJ_SCHEMA));
        } else
            // Schema not created
            System.err.println (String.format(OBJ_NOT_CR, OBJ_SCHEMA));
        // Переподключение к вновь созданной схеме
        if ((idx != idx_derby) && (idx != idx_postgres)) {
            dao.Disconnect(dao.getConnection());
            params[idx][SCHEMA] = SCHEMA_NAME;
            createConnecion (dao, idx);
    }
    // Создание таблицы
    if (schema_created || (idx == idx_oracle)) {
        if (((idx == idx_derby) || (idx == idx_postgres)))
            table_created = dao.execSQL(String.format(TABLE_CREATE, "\"" + SCHEMA_NAME + "\"."));
        else
            table_created = dao.execSQL(String.format(TABLE_CREATE, ""));
        if (table_created)
            // Table created
            System.out.println (String.format(OBJ_CREATED, OBJ_TABLE));
        else
            // Table not created
            System.err.println (String.format(OBJ_NOT_CR, OBJ_TABLE));
    }
}

После создания схемы СУБД MySQL и MSSQL выполняем переподключение к вновь созданной схеме для создания таблицы. В СУБД PostgreSQL и Derby создаем таблицу с указанием наименования схемы, т.е. "MEDIA".USERS .

Процедура удаления схемы и таблицы dropObjects

Процедура сначала удаляет таблицу, после чего удаляет схему, если СУБД не Oracle. Для удаления схемы в MS SQL необходимо "отключиться" от схемы, в противном случае будет ошибка с сообщением, что удалить невозможно в связи с имеющимися подключениями.

/**
 * Процедура удаления объектов СУБД
 * @param dao модуль доступа к СУБД
 * @param idx идентификатор СУБД
 */
private void dropObjects(dao_base dao, final int idx)
{
    // Удаление таблицы
    if (table_created) {
        if ((idx != idx_derby) && (idx != idx_postgres)) {
            if (dao.execSQL(String.format(TABLE_DROP, "")))
                // Table deleted
                System.out.println (String.format(OBJ_DROPED, OBJ_TABLE));
            else
                // Table not deleted
                System.err.println (String.format(OBJ_NOT_DEL, OBJ_TABLE));
        } else {
            if (dao.execSQL(String.format(TABLE_DROP, "\"" + SCHEMA_NAME + "\".")))
                // Table deleted
                System.out.println (String.format(OBJ_DROPED, OBJ_TABLE));
            else
                // Table not deleted
                System.err.println (String.format(OBJ_NOT_DEL, OBJ_TABLE));
        }
    }
    // Отключение от вновь созданной схемы
    if (idx == idx_mssql) {
        // Отключение от схемы для удаления
        dao.Disconnect(dao.getConnection());
        // Очищаем наименование схемы
        params[idx][SCHEMA] = "";
        // Подключение к СУБД
        createConnecion (dao, idx);
    }

    // Удаление схемы
    if (idx != idx_oracle) {
        if (dao.dropSchema(SCHEMA_NAME)) {
            // Schema deleted
            System.out.println (String.format(OBJ_DROPED, OBJ_SCHEMA));
        } else
            // Schema not deleted
            System.err.println (String.format(OBJ_NOT_DEL, OBJ_SCHEMA));
    }
}

Исходный код dao_derby.java

В исходных кодах приведем только описание конструктора "test_jdbc". Все остальные, используемые в примере переменные и методы, представлены выше.

public class test_jdbc
{
	. . .
	public test_jdbc()
	{
		// Определение "модуля доступа к СУБД"
		dao_base dm = null;
		// Цикл перебора параметров подключения к СУБД
		for (int i = 0; i < params.length; i++) {
			// Проверка флага активности СУБД
			if (params[i][ACTIVE].equalsIgnoreCase(String.valueOf(true))) {
				// Создание "модуля доступа" к СУБД 
				switch (i) {
					case 0 : dm = new dao_mysql   (); break;
					case 1 : dm = new dao_mssql   (); break;
					case 2 : dm = new dao_postgres(); break;
					case 3 : dm = new dao_oracle  (); break;
					case 4 : dm = new dao_derby   (); break;
				}
			}
			// Проверка создания dm
			if (dm != null) {
				// Подключение к серверу БД
				createConnecion (dm, i);
				// Вывод в консоль информации о подключении
				if (dm.getConnection() != null) {
					System.out.println (String.format(SUCCESS, params[i][DBMS]));
					// Создание схемы и таблицы
					createObjects(dm, i);
					// Удаление таблицы и схемы
					dropObjects(dm, i);
					// Отключение от сервера БД
					dm.Disconnect(dm.getConnection());
				} else
					System.err.println (String.format(FAILED, params[i][DBMS]));
			}
			dm = null;
		}
	}
	public static void main(String[] args) {
		new test_jdbc();
		System.exit(0);
	}
}

В конструкторе в цикле выполняется создание объекта "dao", после чего выполняется подключение к серверу БД, создается схема и таблица во вновь созданной схеме. После этого вновь созданные объекты удаляются и "dao" отключается от сервера СУБД.

На следующем скриншоте представлены сообщения данного JDBC примера в консоли Eclipse.

  Рейтинг@Mail.ru