Программное JDBC-подключение
Содержание раздела
JDBC-драйвер системы позволяет подключаться программно (без использования SQL-клиента). Вы можете реализовать свое приложение, работающее с системой по JDBC.
Реализация программного JDBC-подключения к системе
Чтобы реализовать программное подключение к системе по JDBC:
- Включите библиотеку JDBC-драйвера в свой проект.
- В реализации класса вашего приложения, отвечающего за подключение к системе (см. базовый пример в секции ниже):
- Импортируйте пакеты Java SQL:
import java.sql.*;
- Если вы используете Java версии менее 1.6, загрузите драйвер в память:
Class.forName("ru.datamart.prostore.jdbc.Driver");
-
(Опционально) Задайте максимальное количество запросов, исполняемых синхронно в одном подключении, с помощью параметра
statementConcurrency
. По умолчанию значение равно 2.Например:
Properties properties = new Properties(); properties.setProperty("statementConcurrency", "1");
-
(Опционально) Задайте размер буфера данных, получаемых от системы Prostore, с помощью параметра
receiveBufferSize
. По умолчанию значение равно 524288 байт (512 Кбайт).Например:
properties.setProperty("receiveBufferSize", "256 * 1024");
- (Опционально) Определите формат передачи данных между драйвером и системой:
- Задайте формат из следующих:
avro
— Avro-формат без сжатия (используется по умолчанию);json
— JSON-строка;avro-deflate
— Avro-формат со сжатием по алгоритму Deflate;avro-snappy
— Avro-формат со сжатием по алгоритму Snappy;avro-bzip2
— Avro-формат со сжатием по алгоритму BZip2;avro-xz
— Avro-формат со сжатием по алгоритму XZ;avro-zstandard
— Avro-формат со сжатием по алгоритму Zstandard.
Например:
properties.setProperty("format", "avro-snappy");
- Если вы используете Avro-формат со сжатием, задайте уровень сжатия данных, например:
properties.setProperty("compressionLevel", "3");
Доступные уровни сжатия данных для каждого из алгоритмов см. в документации Apache Avro.
- Если вы используете Avro-формат
avro-snappy
илиavro-xz
, подключите нужные зависимости:
<dependency> <groupId>org.xerial.snappy</groupId> <artifactId>snappy-java</artifactId> </dependency> <dependency> <groupId>org.tukaani</groupId> <artifactId>xz</artifactId> </dependency>
- Задайте формат из следующих:
- Установите соединение с системой с помощью метода
DriverManager.getConnection()
в следующем формате:// Имя пользователя и авторизационный токен auth_token (если в системе включена аутентификация) properties.setProperty("user", "jwt"); properties.setProperty("password", "auth_token"); // Адрес подключения String url = "jdbc:prostore://ProstoreNodeHost:portNumber/logicalDatabaseName"; // Установка соединения в случае, если аутентификация отключена и используется формат передачи данных по умолчанию (Avro без сжатия) Connection connection = DriverManager.getConnection(url); // Установка соединения в случае, если аутентификация включена и/или используется формат передачи данных, заданный в параметрах подключения Connection connection = DriverManager.getConnection(url, properties);
Где:
prostoreNodeHost
— IP-адрес или имя хоста с нодой Prostore;portNumber
— номер порта для подключения;- (опционально)
logicalDatabaseName
— имя логической базы данных, используемой по умолчанию.
- Выполните вызов нужных запросов SQL+ и по завершении обработки их результатов закройте подключение.
- Импортируйте пакеты Java SQL:
Пример класса для реализации подключения по JDBC
В примере ниже показана базовая реализация класса SimpleDtmJDBCExample
, который задает формат передачи данных (avro-snappy
), устанавливает соединение с системой по указанному адресу и закрывает соединение.
import java.sql.*;
import java.util.Properties;
public class SimpleProstoreJDBCExample {
public static void main(String[] args) {
String url = "jdbc:prostore://10.92.3.3:9090/marketing";
Properties properties = new Properties();
properties.setProperty("user", "jwt");
properties.setProperty("password", "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c");
properties.setProperty("statementConcurrency", "1");
properties.setProperty("receiveBufferSize", "256 * 1024");
properties.setProperty("format", "avro-snappy");
properties.setProperty("compressionLevel", "3");
try (Connection connection = DriverManager.getConnection(url, properties)) {
System.out.println("Connected");
// Добавьте логику работы с подключением
} catch (SQLException error) {
// Добавьте логику обработки SQL-ошибок
error.printStackTrace();
}
}
}
Реализация потокового чтения данных с помощью курсора СУБД
Чтобы после подключения к системе выбрать данные порциями, используя курсор СУБД:
- Перед вызовом SELECT-запроса задайте размер порций данных с помощью метода
Statement.setFetchSize
. - (Опционально) Если необходимо, задайте дополнительные параметры чтения данных:
- максимальное количество записей, возвращаемых по запросу с учетом всех порций данных, — с помощью метода
Statement.setMaxRows
; - максимальное время (в секундах) ожидания ответа по каждой порции данных — с помощью метода
Statement.setQueryTimeout
.
- максимальное количество записей, возвращаемых по запросу с учетом всех порций данных, — с помощью метода
- Откройте курсор с помощью метода
Statement.executeQuery
. - Реализуйте передвижение курсора с помощью метода
ResultSet.next
. - После обработки результатов SELECT-запроса закройте курсор с помощью метода
close
интерфейсаResultSet
,Statement
илиConnection
.
Ниже показан пример с разделением данных на порции по 100 записей, открытием курсора, его сдвигом и закрытием, а также опциональными ограничениями — на максимальное количество записей по запросу (5000 записей
) и на максимальное время ожидания каждого ответа с порцией данных (300 секунд
= 5 минут
).
Полный пример базовой реализации класса см. в секции Пример класса для подключения и потокового чтения данных по JDBC.
Statement statement = connection.createStatement();
// Включение потокового чтения данных порциями указанного размера
statement.setFetchSize(100);
// Максимальное количество записей по запросу. Опциональный параметр, по умолчанию количество не ограничено
statement.setMaxRows(5000);
//Максимальное время исполнения запроса в секундах. Опциональный параметр, по умолчанию время не ограничено
statement.setQueryTimeout(300);
ResultSet resultset = statement.executeQuery("SELECT * FROM sales");
while (resultset.next()) {
// Добавьте требуемую обработку полученных строк
}
resultset.close();
Потоковое чтение данных по JDBC не поддерживает одновременный возврат результатов по нескольким запросам. Это означает, что, если в реализации класса сделан один вызов statement.executeQuery
с несколькими запросами, перечисленными через точку с запятой, результаты каждого следующего запроса вернуться только после возврата всех результатов по предыдущему запросу.
Пример класса для подключения и потокового чтения данных
В примере ниже показана базовая реализация класса StreamingExample
, который устанавливает соединение с системой по заданному адресу, исполняет SELECT-запрос с использованием курсора и затем закрывает курсор и соединение.
import java.sql.*;
public class StreamingExample {
public static void main(String[] args) {
String url = "jdbc:prostore://10.92.3.3:9090/marketing";
try (Connection connection = DriverManager.getConnection(url)) {
System.out.println("Connected");
try (Statement statement = connection.createStatement()) {
// Включение потокового чтения данных порциями по 100 записей
statement.setFetchSize(100);
statement.setMaxRows(5000);
statement.setQueryTimeout(300);
try (ResultSet resultset = statement.executeQuery("SELECT * FROM sales")) {
while (resultset.next()) {
// Добавьте логику обработки полученных строк
}
}
} catch (SQLException error) {
// Добавьте логику обработки SQL-ошибок
error.printStackTrace();
}
}
}
}
Реализация чтения данных с помощью параметризованного запроса (prepared statement)
Чтобы после подключения к системе выбрать данные с помощью параметризованного запроса:
- Создайте параметризованный запрос с помощью метода
Connection.preparedStatement
. - Задайте параметры запроса с помощью методов семейства
PreparedStatement.set
. - Исполните запрос с помощью метода
PreparedStatement.executeQuery
. - Обработайте результат запроса нужным вам образом.
Пример класса для подключения и чтения данных с помощью параметризованного запроса
В примере ниже показана базовая реализация класса PreparedStatementExample
, который устанавливает соединение с системой по заданному адресу, исполняет параметризованный SELECT-запрос и затем закрывает соединение.
import java.sql.*;
public class PreparedStatementExample {
public static void main(String[] args) {
String url = "jdbc:prostore://10.92.3.3:9090/marketing";
ResultSet resultSet = null;
try (Connection connection = DriverManager.getConnection(url)) {
System.out.println("Connected");
// Создание параметризованного SELECT-запроса
String query = "SELECT * FROM sales " +
"FOR SYSTEM_TIME AS OF ? " +
"WHERE id > ?;";
try (PreparedStatement preparedStatement = connection.prepareStatement(query)) {
// Установка значений для запроса
preparedStatement.setTimestamp(1, Timestamp.valueOf("2024-05-10 13:12:09")); // Установка метки времени 10 мая 2024 13:12:09 для FOR SYSTEM_TIME AS OF
preparedStatement.setInt(2, 70); // Установка значения 70 для id
// Выполнение запроса
resultSet = preparedStatement.executeQuery();
while (resultset.next()) {
// Добавьте логику обработки полученных строк
}
} catch (SQLException error) {
// Добавьте логику обработки SQL-ошибок
error.printStackTrace();
}
}
}
}