Рубрики
Без рубрики

Что такое JDBC?

Вступление Итак, вы хотите подключить свое Java-приложение к базе данных. На самом деле это не имеет значения… Помеченный как java, база данных.

Вступление

Итак, вы хотите подключить свое Java-приложение к базе данных. На самом деле не имеет значения, что это за приложение, будь то серверный или интерфейсный графический интерфейс. И также не имеет значения, какая база данных, если MySQL, Postgres или SQLite (или любая другая).

Каждое Java-приложение подключается к базе данных через JDBC API .

Еще лучше то, что вам не нужно явно устанавливать API JDBC или включать его в свой проект в качестве сторонней библиотеки, потому что по умолчанию он поставляется с каждым JDK/JRE .

Единственное, что вам нужно для начала работы с JDBC, – это драйвер для вашей конкретной базы данных.

Драйверы JDBC

Что такое драйвер JDBC?

Чтобы подключиться к вашей базе данных на Java, вам нужен так называемый драйвер JDBC. Каждая база данных ( MySQL , Oracle , PostgreSQL и т.д.) Поставляется со своим собственным драйвером JDBC, обычно созданным поставщиком базы данных и найденным на веб-сайте базы данных.

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

Итак, чтобы подключиться, например, к базе данных MySQL, вам нужно будет перейти на веб-сайт MySQL , загрузить файл MySQL JDBC driver .jar (также называемый: Connector/J) и добавить его в свой проект.

Где я могу найти последнюю версию драйвера JDBC для моей базы данных?

Вот список местоположений драйверов для наиболее популярных баз данных для вашей справки:

Драйверы JDBC и репозитории Maven

Если вы используете Maven или Gradle в вашем проекте, тогда вы бы добавили драйвер JDBC в качестве зависимости в свой проект вместо добавления файла .jar вручную.

Вы найдете теги Maven (координаты) для каждого драйвера JDBC в этом замечательном списке Влада Михалча:

Вы найдете теги Maven (координаты) для каждого драйвера JDBC в этом замечательном списке Влада Михалча:

Итак, в случае MySQL вы бы добавили этот тег в свой pom.xml файл.

    
        mysql
        mysql-connector-java
        8.0.20
    

Соединения JDBC

Открытие подключений к базе данных с помощью JDBC

Как только вы добавили драйвер в свой проект, вы готовы открыть подключения JDBC к вашей базе данных.

Мы добавили драйвер mysql-connector-java , поэтому мы собираемся подключиться к базе данных MySQL. Если вы когда-либо раньше использовали базу данных, это, по сути, будет то же самое, что открыть окно терминала и выполнить команду ‘mysql’ для использования интерфейса командной строки MySQL.

Короче говоря, в конечном итоге вы получите активное подключение к базе данных, а затем сможете запускать свои SQL-инструкции.

Итак, чтобы получить доступ к базе данных MySQL с именем test , запущенной на вашем локальном компьютере, и действительным именем пользователя/паролем, вы должны выполнить следующий код:

package com.marcobehler;

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

public class MyMainClass {

    public static void main(String[] args) {
        try (Connection conn = DriverManager
                .getConnection("jdbc:mysql://localhost/test?serverTimezone=UTC",
                        "myUsername", "myPassword")) {

            // "0" means disabling the timeout, when doing isValid checks
            boolean isValid = conn.isValid(0);
            System.out.println("Do we have a valid db connection? = " + isValid);

            // Do something with the Connection, run some SQL statements
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

Давайте разберемся с этим:

try (Connection conn = DriverManager
        .getConnection("jdbc:mysql://localhost/test?serverTimezone=UTC",
                "myUsername", "myPassword")) {

Самый простой способ открыть подключение к базе данных – вызвать DriverManager.getConnection , который автоматически обнаружит драйвер JDBC, который вы добавили в свой проект ранее.

Он принимает три параметра:

  • [0] URL : Допустимый URL-адрес JDBC. Вы увидите, как они должны выглядеть, в следующем разделе.

  • [1] Имя пользователя : Не требующий объяснений

  • [2] Пароль : Не требующий объяснений

// "0" means disabling the timeout, when doing isValid checks
boolean isValid = conn.isValid(0);
System.out.println("Do we have a valid db connection? = " + isValid);

Как только у вас появится соединение, вы сможете выполнять с его помощью SQL-запросы. Поскольку мы не делаем этот пример слишком сложным, мы просто проверяем, работает ли соединение (и не было ли оно отменено сервером базы данных или чем-то подобным).

Есть еще одна последняя вещь, на которую следует обратить внимание. Давайте снова сделаем шаг назад:

try (Connection conn = DriverManager
        .getConnection("jdbc:mysql://localhost/test?serverTimezone=UTC",
                "myUsername", "myPassword")) {
}

Обратите внимание на блокировку try вокруг нашего вызова getConnection ? Это инструкция try-with-resources , которая гарантирует, что ваше соединение автоматически закроется в конце блока, без необходимости закрывать его вручную. Это удобная функция удобства.

Хорошо, теперь вы знаете, как открывать подключения к базе данных. Давайте теперь взглянем на эти строки подключения JDBC.

Строки подключения JDBC – Объяснены

Строка, переданная описанному выше методу DriverManager.getConnection() , называется строкой подключения JDBC и относится к конкретной базе данных. Более конкретно строка подключения:

  • Всегда начинается с jdbc , за которым следует двоеточие (:).

  • Затем имеет идентификатор для базы данных, например mysql или oracle , за которым следует двоеточие (:).

  • За ним следует строка подключения для конкретной базы данных .

Давайте еще раз проверим наш пример MySQL, приведенный выше:

.getConnection("jdbc:mysql://localhost/test?serverTimezone=UTC",
  1. Он начинается с jdbc :

  2. Затем mysql:

  3. Затем конкретная строка MySQL: localhost/test?serverTimezone=UTC . Часовой пояс сервера – это свойство, которое понимает только сервер MySQL, поэтому это не будет работать, например, для PostgreSQL.

Вот пара примеров того, как эти строки подключения могут выглядеть для других баз данных:

  • MySQL → jdbc:mysql://localhost/mydb

  • Postgres → dbc:postgresql://localhost/test

  • Oracle → jdbc:oracle:thin:@prodHost:1521:ORCLE

  • SQL Server → jdbc:sqlserver://localhost;экземпляр=SQLEXPRESS;Имя базы данных=MYDB

Суть: не волнуйтесь, если ваша строка подключения выглядит сложной . Всегда обращайтесь к документации базы данных, чтобы расшифровать ее.

Хорошую шпаргалку для определения того, как должна выглядеть ваша строка подключения, можно найти здесь: Строки драйвера JDBC .

Запросы и наборы результатов JDBC

Как только у вас будет открытое подключение к базе данных, пришло время запускать ваши SQL-запросы к базе данных. Но как?

Как выполнять запросы JDBC (SQL-запросы)

Давайте посмотрим, как вы будете выполнять свои типичные запросы CRUD SQL:

  • выберите * из…​

  • вставить в…​

  • обновление…​

(Предположим, что connection поступает из источника данных, как и в наших примерах выше.)

Выберите запросы и наборы результатов

// jdbc select from
PreparedStatement selectStatement = connection.prepareStatement("select * from users where first_name =  ?");
selectStatement.setString(1, "John");

// this will return a ResultSet of all users with said name
ResultSet rs = selectStatement.executeQuery();

// will traverse through all found rows
while (rs.next()) {
    String firstName = rs.getString("first_name");
    String lastName = rs.getString("last_name");
    System.out.println("firstName = " + firstName + "," + "lastName= " + lastName );
}

Выбор данных с помощью JDBC состоит из двух частей:

Во-первых, вам нужно будет создать PreparedStatement , который принимает ваш SQL в качестве входных данных, с любыми заполнителями, помеченными как ? . Здесь мы выбираем все из воображаемой таблицы базы данных users с условием where в столбце first_name.

Вы захотите использовать ? заполнители для любых переменных данных (например, имя), чтобы быть в безопасности от SQL-инъекции . Вам нужно будет установить их в вашем подготовленном операторе с помощью правильного установщика ( setString для строк, setting для целых чисел и т.д.). Кроме того, имейте в виду, что заполнители нумеруются, начиная с 1. Итак, если у вас есть только один вопросительный знак, вам нужно будет вызвать setString(1, ваша строка) . Для второго setString(2, какая-то другая строка) и т.д.

Во-вторых, выполнение запроса вернет вам ResultSet , который в основном представляет собой список всех строк, найденных вашей базой данных для данного запроса. И вам придется пройти через этот результирующий набор с помощью цикла while, вызывая rs.next() .

В нашем примере выше мы просто распечатываем first_name и фамилия_имя каждого найденного нами пользователя. Обратите внимание, что результирующий набор предлагает различные методы получения, такие как getString или getInt или getDate , который вам нужно вызвать в зависимости от типов столбцов возвращаемых вами записей базы данных. FirstName и LastName являются строковыми столбцами, поэтому мы просто вызываем getString .

Просто, верно?

Вставка запросов и выполнение обновления

// jdbc insert into
PreparedStatement statement = connection.prepareStatement("insert into users (first_name, last_name) values (?,?)");
statement.setString(1, "John");
statement.setString(2, "Rambo");
int insertedRows = statement.executeUpdate();
System.out.println("I just inserted " + insertedRows + " users");

Вставка строк в базу данных в чем-то похожа на выбор строк. Опять же, вы создаете PreparedStatement, с той лишь разницей, что теперь вы вызываете метод executeUpdate в инструкции (не отвлекайтесь на имя, executeInsert отсутствует).

Еще раз, вы должны использовать PreparedStatement с помощью ? заполнители для защиты от SQL-инъекций.

Вам не придется просматривать результирующий набор со вставками, вместо этого executeUpdate вернет вам фактическое количество вставленных строк (1 в нашем случае, если все работало правильно).

Запросы на обновление и выполнение обновления

// jdbc update
PreparedStatement updateStatement = connection.prepareStatement("update users set first_name = 'unknown' where id = ?");
updateStatement.setInt(1, 1);
int updatedRows = updateStatement.executeUpdate();
System.out.println("I just updated " + updatedRows + " users");

Обновление строк в основном идентично вставке строк. Вы создаете Подготовленный оператор и вызываете executeUpdate для него.

Еще раз, вы должны использовать PreparedStatement с помощью ? заполнители для защиты от SQL-инъекций. executeUpdate теперь вернет вам фактическое количество обновленных строк.

Удалять запросы и выполнять обновление

Они совпадают с приведенными выше запросами на обновление, поэтому мы пока их пропустим.

Объединение соединений JDBC в пул

Что такое объединение соединений JDBC?

Открытие и закрытие подключений к базе данных (например, tcp-сокеты и соединения), как вы делали выше с помощью метода DriverManager.getConnection , занимает некоторое время.

Особенно в веб-приложениях, вы не хотите открывать новое подключение к базе данных для каждого отдельного действия пользователя, скорее вы хотите иметь небольшой пул подключений , которые всегда открыты и доступны совместно между пользователями.

Вот для чего нужны пулы соединений JDBC. Пул подключений поддерживает открытым небольшое количество подключений к базе данных (например, 10), и вместо того, чтобы самостоятельно открывать подключения к базе данных, вы будете запрашивать пул подключений.

Каков наилучший пул подключений JDBC?

К сожалению, в Java land у вас есть множество вариантов, когда дело доходит до пулов подключений:

Проблема со старыми пулами подключений (DBCP/C3P0) заключается в том, что им не хватает правильных, разумных настроек по умолчанию, возникают проблемы с производительностью и обработкой случаев ошибок и находятся – сверху – часто неправильно сконфигурированы.

Поэтому для новых проектов я бы рекомендовал следующие пулы:

HikariCP или Vibur-dbcp как отличный выбор по умолчанию (HikariCP – это выбор Spring Boot по умолчанию). Используйте UCP Oracle , если вы работаете с базами данных Oracle.

Все эти пулы подключений надежны, обладают высокой производительностью и предлагают разумные значения по умолчанию и обработку ошибок.

Как использовать пул подключений JDBC

Независимо от выбранного вами варианта, затем вы в своем коде JDBC не будете самостоятельно открывать соединения через DriverManager, а скорее создадите пул соединений, представленный интерфейсом DataSource , и попросите его предоставить вам одно из своих подключений.

Давайте посмотрим на какой-нибудь код. Это точно такой же код, как и выше (подключение к MySQL), онлайн переписанный для использования DataSource , вместо Диспетчер драйверов .

package com.marcobehler;

import com.zaxxer.hikari.HikariDataSource;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;

public class MyHikariCpClass {

    public static void main(String[] args) {
        DataSource dataSource = createDataSource();

        try (Connection conn = dataSource.getConnection()) {

            // "0" means disabling the timeout, when doing isValid checks
            boolean isValid = conn.isValid(0);
            System.out.println("Do we have a valid db connection? = " + isValid);

            // Do something with the Connection, run some SQL statements
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    private static DataSource createDataSource() {
        HikariDataSource ds = new HikariDataSource();
        ds.setJdbcUrl("jdbc:mysql://localhost/test?serverTimezone=UTC");
        ds.setUsername("myUsername");
        ds.setPassword("myPassword");
        return ds;
    }
}

Давайте разберем это по полочкам.

DataSource dataSource = createDataSource();

Вам нужно создать источник данных пула подключений где-нибудь в вашем приложении. Здесь мы извлекли код создания в другой метод.

private static DataSource createDataSource() {
    HikariDataSource ds = new HikariDataSource();
    ds.setJdbcUrl("jdbc:mysql://localhost/test?serverTimezone=UTC");
    ds.setUsername("myUsername");
    ds.setPassword("myPassword");
    return ds;
}

Это код конфигурации, специфичный для HikariCP. В конце концов, однако, мы просто устанавливаем те же параметры, что и при вызове DriverManager.getConnection() .

try (Connection conn = dataSource.getConnection()) {

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

Отлично! Теперь вам больше не нужно беспокоиться о снижении производительности при открытии и закрытии подключений к базе данных.

Плавник

В этой статье рассматриваются основы JDBC, начиная с драйверов и заканчивая обработкой подключений и SQL-запросов, а также объединением подключений.

Суть такова: при использовании JDBC вы работаете с голым металлом. У вас под рукой вся мощь и скорость SQL и JDBC, но JDBC не имеет удобных функций (подумайте о том, сколько ручной работы требуется для обхода результирующего набора).

Вот тут-то и появляются другие фреймворки и библиотеки баз данных Java. От легких оболочек JDBC до полномасштабных решений ORM, таких как Hibernate/JPA.

Вы можете получить отличный обзор всех этих фреймворков в Java и базы данных: фреймворки и библиотеки статья.

На сегодня все. Спасибо за чтение.

Оригинал: “https://dev.to/marcobehler/what-is-jdbc-3o51”