Внешний ключ SQLite в Java
Ограничение FOREIGN KEY привязывает колонку
зависимой таблицы к первичному ключу родителя.
В SQLite проверка срабатывает только после
PRAGMA foreign_keys = ON на соединении.
Таблица складов и ячеек с явной ссылкой на родителя создаётся так:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.Statement;
public class Main {
public static void main(String[] args) throws Exception {
try (Connection connection = DriverManager.getConnection("jdbc:sqlite:fk_bins.db")) {
connection.createStatement().execute(
"PRAGMA foreign_keys = ON"
);
try (Statement statement = connection.createStatement()) {
statement.execute(
"""
CREATE TABLE IF NOT EXISTS warehouses (
id INTEGER PRIMARY KEY,
code TEXT NOT NULL
)
"""
);
statement.execute(
"""
CREATE TABLE IF NOT EXISTS bins (
id INTEGER PRIMARY KEY,
warehouse_id INTEGER NOT NULL,
label TEXT NOT NULL,
FOREIGN KEY (warehouse_id)
REFERENCES warehouses (id)
)
"""
);
}
PreparedStatement parent = connection.prepareStatement(
"INSERT INTO warehouses (code) VALUES (?)"
);
parent.setString(1, "W1");
parent.executeUpdate();
PreparedStatement child = connection.prepareStatement(
"""
INSERT INTO bins (warehouse_id, label)
VALUES (?, ?)
"""
);
child.setInt(1, 1);
child.setString(2, "A-01");
System.out.println(child.executeUpdate());
}
}
}
Число в warehouse_id должно совпадать с
существующим id склада. Иначе вставка
завершится SQLException:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;
public class Main {
public static void main(String[] args) throws Exception {
try (Connection connection = DriverManager.getConnection("jdbc:sqlite:fk_bins.db")) {
connection.createStatement().execute(
"PRAGMA foreign_keys = ON"
);
try (Statement statement = connection.createStatement()) {
statement.execute(
"""
CREATE TABLE IF NOT EXISTS warehouses (
id INTEGER PRIMARY KEY,
code TEXT NOT NULL
)
"""
);
statement.execute(
"""
CREATE TABLE IF NOT EXISTS bins (
id INTEGER PRIMARY KEY,
warehouse_id INTEGER NOT NULL,
label TEXT NOT NULL,
FOREIGN KEY (warehouse_id)
REFERENCES warehouses (id)
)
"""
);
}
PreparedStatement bad = connection.prepareStatement(
"""
INSERT INTO bins (warehouse_id, label)
VALUES (?, ?)
"""
);
bad.setInt(1, 99);
bad.setString(2, "ghost");
try {
bad.executeUpdate();
} catch (SQLException ex) {
System.out.println("rejected");
}
}
}
}
В fk_bins.db добавьте склад "W2"
и ячейку "B-02" с корректным
warehouse_id. Выведите число затронутых
строк при вставке ячейки.
Попробуйте вставить ячейку с warehouse_id
500 в try. При ошибке выведите
"bad link".
Создайте в новом файле fk_rooms.db
таблицы buildings и rooms со
ссылкой на здание. Добавьте здание и комнату с
валидным ключом.