Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Как подключиться к базе данных через JDBC

Короткий ответ

Добавьте драйвер базы в проект и откройте соединение через DriverManager.getConnection() внутри try с ресурсами. Здесь — SQLite в памяти; запуск: java --enable-native-access=ALL-UNNAMED -cp sqlite-jdbc-3.53.4.0.jar Main.java:

import java.sql.*;
 
void main() throws SQLException {
    try (Connection conn = DriverManager.getConnection("jdbc:sqlite::memory:")) {
        IO.println("Connected to " + conn.getMetaData().getDatabaseProductName());
    }
}

Результат:

Connected to SQLite

Драйвер

Драйвер — отдельная библиотека для каждой СУБД. В Maven его добавляют зависимостью, например для PostgreSQL:

<dependency>
    <groupId>org.postgresql</groupId>
    <artifactId>postgresql</artifactId>
    <version>42.7.4</version>
</dependency>

Для MySQL это com.mysql:mysql-connector-j, для SQLite — org.xerial:sqlite-jdbc. Драйвер регистрируется сам, вызывать Class.forName() не нужно.

Адрес, логин и пароль

Адрес начинается с jdbc: и имени СУБД. Пароль лучше брать из переменной окружения, а не писать в коде:

// src/main/java/shop/Database.java
package shop;
 
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
 
public class Database {
    private static final String URL = "jdbc:postgresql://localhost:5432/shop";
    // MySQL:  jdbc:mysql://localhost:3306/shop
    // SQLite: jdbc:sqlite:shop.db
 
    public static Connection connect() throws SQLException {
        return DriverManager.getConnection(URL, "app", System.getenv("DB_PASSWORD"));
    }
}

Первый запрос

Через соединение создают Statement и выполняют SQL:

import java.sql.*;
 
void main() throws SQLException {
    try (Connection conn = DriverManager.getConnection("jdbc:sqlite::memory:");
         Statement st = conn.createStatement()) {
        st.executeUpdate("CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT)");
        st.executeUpdate("INSERT INTO users (name) VALUES ('Anna'), ('Oleg')");
 
        try (ResultSet rs = st.executeQuery("SELECT id, name FROM users")) {
            while (rs.next()) {
                IO.println(rs.getInt("id") + " " + rs.getString("name"));
            }
        }
    }
}

Результат:

1 Anna
2 Oleg

Значения из ввода пользователя в SQL не склеивают — для них есть PreparedStatement.

Частая ошибка

Забыть добавить драйвер. Программа компилируется, но при подключении падает:

import java.sql.*;
 
void main() throws SQLException {
    DriverManager.getConnection("jdbc:postgresql://localhost:5432/shop", "app", "secret");
}

Результат:

Exception in thread "main" java.sql.SQLException: No suitable driver found for jdbc:postgresql://localhost:5432/shop

Ещё одна ошибка — не закрывать соединения. Каждое держит ресурсы базы, и через некоторое время новые подключения перестанут открываться. В веб-приложениях используют пул соединений, например HikariCP.

Функции из этого ответа

  • DriverManager.getConnection() — Открывает соединение с базой данных по JDBC-адресу.
  • PreparedStatement — Заранее подготовленный SQL-запрос с параметрами ?. Защищает от SQL-инъекций.
  • ResultSet — Результат SELECT-запроса: курсор, который по одной перебирает строки таблицы.
  • try-with-resources — Блок `try`, который сам закрывает открытые ресурсы — файлы, соединения, потоки.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.