Skip to content

SQLite - Java

本指南演示了在 Java 应用程序中使用 SQLite 的现代最佳实践方法,重点关注依赖管理、资源安全和安全编码。

手动下载 JAR 文件是一种过时且容易出错的做法。现代 Java 项目使用 Maven 或 Gradle 等构建自动化工具来管理依赖。

将以下依赖添加到您的 pom.xml 文件中。这将自动下载 SQLite JDBC 驱动。

<!-- pom.xml -->
<dependencies>
<dependency>
<groupId>org.xerial</groupId>
<artifactId>sqlite-jdbc</artifactId>
<version>3.45.1.0</version> <!-- 检查最新版本 -->
</dependency>
</dependencies>

对于 Gradle 项目,将其添加到您的 build.gradle 文件中:

build.gradle
dependencies {
implementation 'org.xerial:sqlite-jdbc:3.45.1.0' // 检查最新版本
}

使用现代 JDBC 4.0+ 驱动程序,您不再需要 Class.forName()。驱动程序会自动从 classpath 中检测到。一个健壮的连接方法应该集中管理。

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class DatabaseManager {
private static final String DB_URL = "jdbc:sqlite:company.db";
public static Connection connect() throws SQLException {
return DriverManager.getConnection(DB_URL);
}
}

最佳实践:try-with-resources 和 PreparedStatement

Section titled “最佳实践:try-with-resources 和 PreparedStatement”

为了防止资源泄露,请始终使用 try-with-resources 语句。为了防止 SQL 注入漏洞,对于带参数的查询,请始终使用 PreparedStatement。

让我们使用数据访问对象 (DAO) 模式来组织代码。这将数据库操作与我们的主要应用程序逻辑分离,使代码更清晰,更易于测试。

import java.sql.*;
import java.util.ArrayList;
import java.util.List;
// 一个简单的 Employee 数据类
record Employee(int id, String name, int age, String address, double salary) {}
// 处理所有数据库操作的 DAO 类
class EmployeeDAO {
public void createTable() {
String sql = "CREATE TABLE IF NOT EXISTS employees (\n"
+ " id INTEGER PRIMARY KEY,\n"
+ " name TEXT NOT NULL,\n"
+ " age INTEGER NOT NULL,\n"
+ " address TEXT,\n"
+ " salary REAL\n"
+ ");";
try (Connection conn = DatabaseManager.connect();
Statement stmt = conn.createStatement()) {
stmt.execute(sql);
System.out.println("Table 'employees' is ready.");
} catch (SQLException e) {
System.err.println(e.getMessage());
}
}
public void insert(Employee employee) {
String sql = "INSERT INTO employees(name, age, address, salary) VALUES(?,?,?,?)";
try (Connection conn = DatabaseManager.connect();
PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmt.setString(1, employee.name());
pstmt.setInt(2, employee.age());
pstmt.setString(3, employee.address());
pstmt.setDouble(4, employee.salary());
pstmt.executeUpdate();
System.out.println(employee.name() + " inserted.");
} catch (SQLException e) {
System.err.println(e.getMessage());
}
}
public List<Employee> selectAll() {
String sql = "SELECT id, name, age, address, salary FROM employees";
List<Employee> employees = new ArrayList<>();
try (Connection conn = DatabaseManager.connect();
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(sql)) {
while (rs.next()) {
employees.add(new Employee(
rs.getInt("id"),
rs.getString("name"),
rs.getInt("age"),
rs.getString("address"),
rs.getDouble("salary"))
);
}
} catch (SQLException e) {
System.err.println(e.getMessage());
}
return employees;
}
public void updateSalary(int id, double newSalary) {
String sql = "UPDATE employees SET salary = ? WHERE id = ?";
try (Connection conn = DatabaseManager.connect();
PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmt.setDouble(1, newSalary);
pstmt.setInt(2, id);
int affectedRows = pstmt.executeUpdate();
System.out.println(affectedRows + " record(s) updated.");
} catch (SQLException e) {
System.err.println(e.getMessage());
}
}
public void delete(int id) {
String sql = "DELETE FROM employees WHERE id = ?";
try (Connection conn = DatabaseManager.connect();
PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmt.setInt(1, id);
int affectedRows = pstmt.executeUpdate();
System.out.println(affectedRows + " record(s) deleted.");
} catch (SQLException e) {
System.err.println(e.getMessage());
}
}
}
// 运行演示的主应用程序类
public class Main {
public static void main(String[] args) {
EmployeeDAO dao = new EmployeeDAO();
// 1. 设置
dao.createTable();
// 2. 插入 (创建)
dao.insert(new Employee(0, "Paul", 32, "California", 20000.00));
dao.insert(new Employee(0, "Allen", 25, "Texas", 15000.00));
dao.insert(new Employee(0, "Teddy", 23, "Norway", 20000.00));
// 3. 查询 (读取)
System.out.println("\n--- Current Employees ---");
dao.selectAll().forEach(System.out::println);
// 4. 更新
System.out.println("\n--- Updating Paul's Salary ---");
dao.updateSalary(1, 25000.00);
dao.selectAll().forEach(System.out::println);
// 5. 删除
System.out.println("\n--- Deleting Allen ---");
dao.delete(2);
dao.selectAll().forEach(System.out::println);
}
}

要测试 EmployeeDAO,您可以使用 JUnit 5 等测试框架。一种常见做法是将 JDBC URL 配置为在测试中使用内存数据库 (jdbc:sqlite::memory:)。这确保您的测试快速、独立,并且不会在文件系统上留下任何产物。