Java JDBC API
Установка
API DuckDB Java JDBC можно установить из Maven Central. Подробности см. на странице установки.
Базовое использование API
API JDBC DuckDB реализует основные части стандартного API Java Database Connectivity (JDBC) версии 4.1. Описание JDBC выходит за рамки этой страницы; см. официальную документацию для получения подробностей. Ниже мы сосредоточимся на специфичных для DuckDB частях.
Для получения дополнительной информации об наших расширениях спецификации JDBC обратитесь к справочнику API или к разделу ниже Методы Arrow.
Запуск и завершение
В JDBC подключения к базам данных создаются с помощью стандартного класса java.sql.DriverManager. Драйвер должен автоматически зарегистрироваться в DriverManager, если это по какой-либо причине не работает, вы можете принудительно зарегистрировать его, используя следующее утверждение:
Class.forName("org.duckdb.DuckDBDriver"); Для создания подключения к DuckDB вызовите DriverManager с префиксом URL JDBC jdbc:duckdb:, как показано ниже:
import java.sql.Connection;
import java.sql.DriverManager;
Connection conn = DriverManager.getConnection("jdbc:duckdb:"); Чтобы использовать функции, специфичные для DuckDB, такие как Appender, приведите объект к типу DuckDBConnection:
import java.sql.DriverManager;
import org.duckdb.DuckDBConnection;
DuckDBConnection conn = (DuckDBConnection) DriverManager.getConnection("jdbc:duckdb:"); При использовании только URL jdbc:duckdb: создается база данных в памяти. Обратите внимание, что для базы данных в памяти данные не сохраняются на диск (то есть все данные теряются при выходе из программы Java). Если вы хотите получить доступ к постоянной базе данных или создать её, добавьте имя файла после пути. Например, если ваша база данных хранится в /tmp/my_database, используйте URL JDBC jdbc:duckdb:/tmp/my_database для создания к ней подключения.
Возможна работа с файлом базы данных DuckDB в только для чтения режиме. Это, например, полезно, если несколько процессов Java хотят одновременно читать один и тот же файл базы данных. Чтобы открыть существующий файл базы данных в режиме только для чтения, установите свойство подключения duckdb.read_only следующим образом:
Properties readOnlyProperty = new Properties();
readOnlyProperty.setProperty("duckdb.read_only", "true");
Connection conn = DriverManager.getConnection("jdbc:duckdb:/tmp/my_database", readOnlyProperty); Дополнительные подключения можно создать, используя DriverManager. Более эффективный механизм — вызов метода DuckDBConnection#duplicate():
Connection conn2 = ((DuckDBConnection) conn).duplicate();
Разрешено несколько подключений, но смешивание подключений для чтения/записи и только для чтения не поддерживается.
Настройка подключений
Параметры конфигурации могут быть предоставлены для изменения различных настроек системы баз данных. Обратите внимание, что многие из этих параметров можно изменить позже, используя также PRAGMA утверждения.
Properties connectionProperties = new Properties();
connectionProperties.setProperty("temp_directory", "/path/to/temp/dir/");
Connection conn = DriverManager.getConnection("jdbc:duckdb:/tmp/my_database", connectionProperties); Запросы
DuckDB поддерживает стандартные методы JDBC для отправки запросов и получения наборов результатов. Сначала необходимо создать объект Statement из Connection, а затем этот объект можно использовать для отправки запросов с помощью execute и executeQuery. execute() предназначен для запросов, не ожидающих результатов, таких как CREATE TABLE или UPDATE и т. д., а executeQuery() предназначен для использования в запросах, которые производят результаты (например, SELECT). Ниже приведены два примера. См. также документацию JDBC по Statement и ResultSet.
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
Connection conn = DriverManager.getConnection("jdbc:duckdb:");
// create a table
Statement stmt = conn.createStatement();
stmt.execute("CREATE TABLE items (item VARCHAR, value DECIMAL(10, 2), count INTEGER)");
// insert two items into the table
stmt.execute("INSERT INTO items VALUES ('jeans', 20.0, 1), ('hammer', 42.2, 2)");
try (ResultSet rs = stmt.executeQuery("SELECT * FROM items")) {
while (rs.next()) {
System.out.println(rs.getString(1));
System.out.println(rs.getInt(3));
}
}
stmt.close(); jeans 1 hammer 2
DuckDB также поддерживает подготовленные запросы в соответствии с API JDBC:
import java.sql.PreparedStatement;
try (PreparedStatement stmt = conn.prepareStatement("INSERT INTO items VALUES (?, ?, ?);")) {
stmt.setString(1, "chainsaw");
stmt.setDouble(2, 500.0);
stmt.setInt(3, 42);
stmt.execute();
// more calls to execute() possible
} Предупреждение Не используйте подготовленные запросы для вставки большого объёма данных в DuckDB. См. документацию по импорту данных для лучших вариантов.
Методы Arrow
Обратитесь к справочнику API для получения информации о типах.
Экспорт Arrow
Следующий пример демонстрирует экспорт потока arrow и его использование с помощью Java Arrow bindings
import org.apache.arrow.memory.RootAllocator;
import org.apache.arrow.vector.ipc.ArrowReader;
import org.duckdb.DuckDBResultSet;
try (var conn = DriverManager.getConnection("jdbc:duckdb:");
var stmt = conn.prepareStatement("SELECT * FROM generate_series(2000)");
var resultset = (DuckDBResultSet) stmt.executeQuery();
var allocator = new RootAllocator()) {
try (var reader = (ArrowReader) resultset.arrowExportStream(allocator, 256)) {
while (reader.loadNextBatch()) {
System.out.println(reader.getVectorSchemaRoot().getVector("generate_series"));
}
}
stmt.close();
} Импорт Arrow
Следующий пример демонстрирует использование потока Arrow из Java Arrow bindings.
import org.apache.arrow.memory.RootAllocator;
import org.apache.arrow.vector.ipc.ArrowReader;
import org.duckdb.DuckDBConnection;
// Arrow binding
try (var allocator = new RootAllocator();
ArrowStreamReader reader = null; // should not be null of course
var arrow_array_stream = ArrowArrayStream.allocateNew(allocator)) {
Data.exportArrayStream(allocator, reader, arrow_array_stream);
// DuckDB setup
try (var conn = (DuckDBConnection) DriverManager.getConnection("jdbc:duckdb:")) {
conn.registerArrowStream("asdf", arrow_array_stream);
// run a query
try (var stmt = conn.createStatement();
var rs = (DuckDBResultSet) stmt.executeQuery("SELECT count(*) FROM asdf")) {
while (rs.next()) {
System.out.println(rs.getInt(1));
}
}
}
} Потоковая передача результатов
Потоковая передача результатов включена в драйвер JDBC — путем установки конфигурации jdbc_stream_results в true перед запуском запроса. Самый простой способ сделать это — передать его в объект Properties.
Properties props = new Properties();
props.setProperty(DuckDBDriver.JDBC_STREAM_RESULTS, String.valueOf(true));
Connection conn = DriverManager.getConnection("jdbc:duckdb:", props); Appender
Appender доступен в драйвере DuckDB JDBC через класс org.duckdb.DuckDBAppender. Конструктор класса требует имени схемы и имени таблицы, к которой он применяется. Appender сбрасывается при вызове метода close().
Пример:
import java.sql.DriverManager;
import java.sql.Statement;
import org.duckdb.DuckDBConnection;
DuckDBConnection conn = (DuckDBConnection) DriverManager.getConnection("jdbc:duckdb:");
try (var stmt = conn.createStatement()) {
stmt.execute("CREATE TABLE tbl (x BIGINT, y FLOAT, s VARCHAR)"
);
// using try-with-resources to automatically close the appender at the end of the scope
try (var appender = conn.createAppender(DuckDBConnection.DEFAULT_SCHEMA, "tbl")) {
appender.beginRow();
appender.append(10);
appender.append(3.2);
appender.append("hello");
appender.endRow();
appender.beginRow();
appender.append(20);
appender.append(-8.1);
appender.append("world");
appender.endRow();
} Блочный писатель
Драйвер DuckDB JDBC предлагает функциональность пакетной записи. Блочный писатель поддерживает подготовленные запросы для снижения накладных расходов на разбор запросов.
Предпочтительный метод для массового вставки — использовать Appender из-за его высокой производительности. Однако, когда использование Appender невозможно, доступен блочный писатель как альтернатива.
Блочный писатель с подготовленными запросами
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import org.duckdb.DuckDBConnection;
DuckDBConnection conn = (DuckDBConnection) DriverManager.getConnection("jdbc:duckdb:");
PreparedStatement stmt = conn.prepareStatement("INSERT INTO test (x, y, z) VALUES (?, ?, ?);");
stmt.setObject(1, 1);
stmt.setObject(2, 2);
stmt.setObject(3, 3);
stmt.addBatch();
stmt.setObject(1, 4);
stmt.setObject(2, 5);
stmt.setObject(3, 6);
stmt.addBatch();
stmt.executeBatch();
stmt.close(); Блочный писатель с обычными запросами
Блочный писатель также поддерживает обычные SQL-запросы:
import java.sql.DriverManager;
import java.sql.Statement;
import org.duckdb.DuckDBConnection;
DuckDBConnection conn = (DuckDBConnection) DriverManager.getConnection("jdbc:duckdb:");
Statement stmt = conn.createStatement();
stmt.execute("CREATE TABLE test (x INTEGER, y INTEGER, z INTEGER)");
stmt.addBatch("INSERT INTO test (x, y, z) VALUES (1, 2, 3);");
stmt.addBatch("INSERT INTO test (x, y, z) VALUES (4, 5, 6);");
stmt.executeBatch();
stmt.close(); Отладка
Класс драйвера не найден
Если приложение Java не может найти DuckDB, может возникнуть следующая ошибка:
Exception in thread "main" java.sql.SQLException: No suitable driver found for jdbc:duckdb:
at java.sql/java.sql.DriverManager.getConnection(DriverManager.java:706)
at java.sql/java.sql.DriverManager.getConnection(DriverManager.java:252)
... И при попытке загрузить класс вручную, может возникнуть эта ошибка:
Exception in thread "main" java.lang.ClassNotFoundException: org.duckdb.DuckDBDriver
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520)
at java.base/java.lang.Class.forName0(Native Method)
at java.base/java.lang.Class.forName(Class.java:375)
... Эти ошибки возникают из-за того, что зависимость DuckDB Maven/Gradle не распознается. Чтобы убедиться, что она распознаётся, обновите конфигурацию Maven в вашем IDE.
© Copyright 2018–2024 Stichting DuckDB Foundation
Licensed under the MIT License.
https://duckdb.org/docs/api/java.html