Вступление
Итак, вы хотите подключить свое 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",
Он начинается с
jdbc:Затем
mysql:Затем конкретная строка MySQL:
localhost/test?serverTimezone=UTC. Часовой пояс сервера – это свойство, которое понимает только сервер MySQL, поэтому это не будет работать, например, для PostgreSQL.
Вот пара примеров того, как эти строки подключения могут выглядеть для других баз данных:
MySQL →
jdbc:mysql://localhost/mydbPostgres →
dbc:postgresql://localhost/testOracle →
jdbc:oracle:thin:@prodHost:1521:ORCLESQL 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 у вас есть множество вариантов, когда дело доходит до пулов подключений:
Старые, устаревшие пулы: Apache Commons DBCP и C3P0 .
HikariCP ( рекомендуется )
Проблема со старыми пулами подключений (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”