Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
# JDBC (Java Database Connectivity) - Полный обзор
Определение
JDBC — это API (Application Programming Interface) в Java, позволяющая подключаться к реляционным базам данных и выполнять SQL операции (INSERT, SELECT, UPDATE, DELETE). Это стандартный способ работы с БД в Java.
История и место в архитектуре
Java Application
↓
JDBC API (ваш код)
↓
JDBC Driver Manager
↓
Database Driver (MySQL, PostgreSQL, Oracle и т.д.)
↓
Database (MySQL, PostgreSQL, Oracle и т.д.)
Основные компоненты JDBC
1. DriverManager - управление драйверами
import java.sql.*;
public class JDBCExample {
public static void main(String[] args) {
// Шаг 1: Загружаем драйвер
try {
Class.forName("com.mysql.cj.jdbc.Driver");
System.out.println("Driver loaded successfully");
} catch (ClassNotFoundException e) {
System.out.println("Driver not found: " + e.getMessage());
}
// Шаг 2: Создаём подключение через DriverManager
String url = "jdbc:mysql://localhost:3306/mydb";
String user = "root";
String password = "password";
try (Connection conn = DriverManager.getConnection(url, user, password)) {
System.out.println("Connected to database");
} catch (SQLException e) {
System.out.println("Connection failed: " + e.getMessage());
}
}
}
2. Connection - подключение к БД
public class DatabaseConnection {
private static final String URL = "jdbc:mysql://localhost:3306/users_db";
private static final String USER = "root";
private static final String PASSWORD = "password";
public static Connection getConnection() throws SQLException {
return DriverManager.getConnection(URL, USER, PASSWORD);
}
public static void main(String[] args) {
try (Connection conn = getConnection()) {
if (conn != null) {
System.out.println("Connected to: " +
conn.getMetaData().getDatabaseProductName());
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
3. Statement - выполнение SQL команд
public class StatementExample {
public static void main(String[] args) {
String url = "jdbc:mysql://localhost:3306/users_db";
String user = "root";
String password = "password";
try (Connection conn = DriverManager.getConnection(url, user, password)) {
// Создаём Statement
Statement stmt = conn.createStatement();
// Выполняем SELECT
String query = "SELECT * FROM users WHERE age > 18";
ResultSet rs = stmt.executeQuery(query);
// Обрабатываем результаты
while (rs.next()) {
int id = rs.getInt("id");
String name = rs.getString("name");
int age = rs.getInt("age");
System.out.println(id + ": " + name + " (" + age + ")");
}
// Выполняем INSERT
String insertSQL = "INSERT INTO users (name, age) VALUES ('John', 25)";
int insertedRows = stmt.executeUpdate(insertSQL);
System.out.println("Inserted " + insertedRows + " row(s)");
} catch (SQLException e) {
e.printStackTrace();
}
}
}
4. PreparedStatement - безопасное выполнение с параметрами
public class PreparedStatementExample {
public static void main(String[] args) {
String url = "jdbc:mysql://localhost:3306/users_db";
String user = "root";
String password = "password";
try (Connection conn = DriverManager.getConnection(url, user, password)) {
// SQL с плейсхолдерами (?)
String query = "SELECT * FROM users WHERE age > ? AND name LIKE ?";
// Создаём PreparedStatement
PreparedStatement pstmt = conn.prepareStatement(query);
pstmt.setInt(1, 18); // Первый параметр - возраст
pstmt.setString(2, "J%"); // Второй параметр - имя
ResultSet rs = pstmt.executeQuery();
while (rs.next()) {
System.out.println(rs.getString("name"));
}
// Безопаснее от SQL injection!
// Плохо: String query = "SELECT * FROM users WHERE age > " + userAge;
// Хорошо: pstmt.setInt(1, userAge);
} catch (SQLException e) {
e.printStackTrace();
}
}
}
5. ResultSet - результаты запроса
public class ResultSetExample {
public static void queryDatabase() throws SQLException {
String url = "jdbc:mysql://localhost:3306/users_db";
String query = "SELECT id, name, email, age FROM users";
try (Connection conn = DriverManager.getConnection(url, "root", "password");
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(query)) {
// Проход по результатам
while (rs.next()) {
// Получение значений по индексу
int id = rs.getInt(1);
String name = rs.getString(2);
String email = rs.getString(3);
int age = rs.getInt(4);
System.out.println(id + " - " + name + " - " + email);
}
// Иная навигация
rs.last(); // Перейти на последнюю строку
System.out.println("Total rows: " + rs.getRow());
rs.first(); // Вернуться на первую
rs.previous(); // Предыдущая строка
rs.absolute(5); // Строка номер 5
} catch (SQLException e) {
System.err.println("Error: " + e.getMessage());
}
}
}
Практический пример: CRUD операции
public class UserDAO {
private String url = "jdbc:mysql://localhost:3306/users_db";
private String user = "root";
private String password = "password";
// CREATE
public void insertUser(String name, String email, int age) throws SQLException {
String query = "INSERT INTO users (name, email, age) VALUES (?, ?, ?)";
try (Connection conn = DriverManager.getConnection(url, user, password);
PreparedStatement pstmt = conn.prepareStatement(query)) {
pstmt.setString(1, name);
pstmt.setString(2, email);
pstmt.setInt(3, age);
int rowsInserted = pstmt.executeUpdate();
System.out.println("Rows inserted: " + rowsInserted);
}
}
// READ
public void selectAllUsers() throws SQLException {
String query = "SELECT * FROM users";
try (Connection conn = DriverManager.getConnection(url, user, password);
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(query)) {
while (rs.next()) {
System.out.println(rs.getInt("id") + " - " +
rs.getString("name") + " - " +
rs.getString("email"));
}
}
}
// UPDATE
public void updateUser(int id, String email) throws SQLException {
String query = "UPDATE users SET email = ? WHERE id = ?";
try (Connection conn = DriverManager.getConnection(url, user, password);
PreparedStatement pstmt = conn.prepareStatement(query)) {
pstmt.setString(1, email);
pstmt.setInt(2, id);
int rowsUpdated = pstmt.executeUpdate();
System.out.println("Rows updated: " + rowsUpdated);
}
}
// DELETE
public void deleteUser(int id) throws SQLException {
String query = "DELETE FROM users WHERE id = ?";
try (Connection conn = DriverManager.getConnection(url, user, password);
PreparedStatement pstmt = conn.prepareStatement(query)) {
pstmt.setInt(1, id);
int rowsDeleted = pstmt.executeUpdate();
System.out.println("Rows deleted: " + rowsDeleted);
}
}
}
// Использование
public static void main(String[] args) throws SQLException {
UserDAO dao = new UserDAO();
dao.insertUser("John", "john@mail.com", 25);
dao.selectAllUsers();
dao.updateUser(1, "newemail@mail.com");
dao.deleteUser(1);
}
JDBC vs ORM (Hibernate/JPA)
JDBC (низкоуровневый)
// Полный контроль, но много кода
String query = "SELECT * FROM users WHERE age > ?";
PreparedStatement pstmt = conn.prepareStatement(query);
pstmt.setInt(1, 18);
ResultSet rs = pstmt.executeQuery();
while (rs.next()) {
User user = new User();
user.setId(rs.getInt("id"));
user.setName(rs.getString("name"));
user.setAge(rs.getInt("age"));
// ...
}
JPA/Hibernate (высокоуровневый)
// Меньше кода, но меньше контроля
List<User> users = entityManager.createQuery(
"SELECT u FROM User u WHERE u.age > :age",
User.class
).setParameter("age", 18)
.getResultList();
Современный подход: использование Connection Pools
import javax.sql.DataSource;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
public class DatabasePool {
private static HikariDataSource dataSource;
static {
HikariConfig config = new HikariConfig();
config.setJdbcUrl("jdbc:mysql://localhost:3306/mydb");
config.setUsername("root");
config.setPassword("password");
config.setMaximumPoolSize(10); // Максимум 10 соединений
config.setMinimumIdle(5); // Минимум 5 соединений
dataSource = new HikariDataSource(config);
}
public static Connection getConnection() throws SQLException {
return dataSource.getConnection();
}
public static void close() {
if (dataSource != null) {
dataSource.close();
}
}
}
Обработка исключений
public class SQLErrorHandling {
public static void demonstrateErrorHandling() {
try {
Connection conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/nonexistent",
"root",
"password"
);
} catch (SQLException e) {
// Получить SQL состояние
String sqlState = e.getSQLState();
// Получить код ошибки
int errorCode = e.getErrorCode();
System.out.println("SQL State: " + sqlState);
System.out.println("Error Code: " + errorCode);
System.out.println("Message: " + e.getMessage());
// Обработать специфичные ошибки
switch (errorCode) {
case 1045:
System.out.println("Access denied");
break;
case 1049:
System.out.println("Unknown database");
break;
default:
System.out.println("Unknown error");
}
}
}
}
Транзакции в JDBC
public class TransactionExample {
public static void transferMoney(int fromAccount, int toAccount,
double amount) throws SQLException {
String url = "jdbc:mysql://localhost:3306/bank";
try (Connection conn = DriverManager.getConnection(url, "root", "pwd")) {
// Отключаем автоматический коммит
conn.setAutoCommit(false);
try {
// Снять деньги со счёта FROM
String debit = "UPDATE accounts SET balance = balance - ? " +
"WHERE id = ?";
PreparedStatement pstmt1 = conn.prepareStatement(debit);
pstmt1.setDouble(1, amount);
pstmt1.setInt(2, fromAccount);
pstmt1.executeUpdate();
// Положить деньги на счёт TO
String credit = "UPDATE accounts SET balance = balance + ? " +
"WHERE id = ?";
PreparedStatement pstmt2 = conn.prepareStatement(credit);
pstmt2.setDouble(1, amount);
pstmt2.setInt(2, toAccount);
pstmt2.executeUpdate();
// Если всё ОК, коммитим
conn.commit();
System.out.println("Transfer successful");
} catch (SQLException e) {
// При ошибке откатываем
conn.rollback();
System.out.println("Transfer failed, rolled back");
throw e;
}
}
}
}
JDBC сегодня: актуальна ли?
✅ JDBC актуален:
- Необходим для сложных запросов, где ORM неэффективен
- Нужен для микрооптимизации производительности
- Используется под капотом большинством ORM
- Essential для понимания как работает БД
❌ Избегай JDBC когда:
- Можешь использовать JPA/Hibernate
- Нет особых требований к производительности
- Проект большой и требует масштабируемости
Резюме
JDBC — это фундаментальный API для работы с БД в Java:
- DriverManager — управление драйверами БД
- Connection — подключение к БД
- Statement/PreparedStatement — выполнение SQL
- ResultSet — получение результатов
Хотя современные приложения чаще используют ORM (Hibernate/JPA), понимание JDBC критически важно для:
- Оптимизации запросов
- Отладки проблем
- Сложных SQL операций
- Интеграции с существующим кодом