杰瑞科技汇

SQLite JDBC Java如何连接使用?

Of course! Here is a comprehensive guide on how to use SQLite with JDBC in Java, covering setup, basic operations, best practices, and advanced features.

SQLite JDBC Java如何连接使用?-图1
(图片来源网络,侵删)

What is SQLite and Why Use it with JDBC?

  • SQLite is a C-language library that implements a small, fast, self-contained, high-reliability, full-featured, SQL database engine. It's often called a "serverless" database because it reads and writes directly to a single disk file.
  • JDBC (Java Database Connectivity) is an API that allows Java applications to interact with databases. It provides methods for querying and updating data in a database.

Key Advantages of using SQLite with JDBC:

  • Zero Configuration: No separate database server to install, configure, or manage.
  • Serverless: The database is a single file, making it incredibly easy to deploy and backup.
  • Self-Contained: No external dependencies.
  • Excellent for: Mobile apps, desktop apps, data analysis, testing, and as an embedded database for Java applications.

Setting Up Your Project

The first step is to add the SQLite JDBC driver to your project. The most common and recommended library is Xerial's SQLite-JDBC.

Using Maven (Recommended)

If you're using Maven, add the following dependency to your pom.xml file. The latest version can be found on the Maven Central Repository.

<dependency>
    <groupId>org.xerial</groupId>
    <artifactId>sqlite-jdbc</artifactId>
    <version>3.45.3.0</version> <!-- Check for the latest version -->
</dependency>

Using Gradle

If you're using Gradle, add this to your build.gradle file:

SQLite JDBC Java如何连接使用?-图2
(图片来源网络,侵删)
implementation 'org.xerial:sqlite-jdbc:3.45.3.0' // Check for the latest version

Manual JAR Download

If you're not using a build tool, you can download the JAR directly from the Maven Central Repository and add it to your project's classpath.


Establishing a Connection

Connecting to a SQLite database is straightforward. The database will be created automatically if it doesn't exist.

  • Connection URL Format: jdbc:sqlite:path_to_database_file
  • path_to_database_file can be a relative path (e.g., mydatabase.db) or an absolute path.

Important Note on In-Memory Databases: For testing or temporary data, you can use an in-memory database. It will be created in RAM and will be destroyed when the connection is closed.

  • URL: jdbc:sqlite::memory:

Code Example: Basic Connection

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class SQLiteJDBC {
    public static void main(String[] args) {
        // The database file will be created in the project's root directory
        String url = "jdbc:sqlite:mydatabase.db";
        try (Connection conn = DriverManager.getConnection(url)) {
            if (conn != null) {
                System.out.println("Connection to SQLite has been established.");
            }
        } catch (SQLException e) {
            System.out.println(e.getMessage());
        }
    }
}

Explanation:

  • We use a try-with-resources block for the Connection. This ensures that the connection is automatically closed when the block is exited, preventing resource leaks.
  • DriverManager.getConnection(url) attempts to establish a connection.
  • The SQLException block catches any potential errors during the connection process.

Basic CRUD Operations (Create, Read, Update, Delete)

Let's perform the standard database operations. We'll continue using the try-with-resources pattern for Connection, Statement, and ResultSet to ensure everything is closed properly.

Create (CREATE TABLE and INSERT)

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
import java.sql.SQLException;
public class CreateSQLiteDB {
    public static void main(String[] args) {
        String url = "jdbc:sqlite:mydatabase.db";
        // SQL statement for creating a new table
        String sql = "CREATE TABLE IF NOT EXISTS users (\n"
                + " id integer PRIMARY KEY,\n"
                + " name text NOT NULL,\n"
                + " email text NOT NULL UNIQUE\n"
                + ");";
        try (Connection conn = DriverManager.getConnection(url);
             Statement stmt = conn.createStatement()) {
            // create a new table
            stmt.execute(sql);
            System.out.println("Table 'users' created successfully.");
            // Insert data
            String insertSql = "INSERT INTO users(name, email) VALUES('Alice', 'alice@example.com');"
                              + "INSERT INTO users(name, email) VALUES('Bob', 'bob@example.com');";
            stmt.execute(insertSql);
            System.out.println("Data inserted successfully.");
        } catch (SQLException e) {
            System.out.println(e.getMessage());
        }
    }
}

Read (SELECT)

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class ReadSQLiteDB {
    public static void main(String[] args) {
        String url = "jdbc:sqlite:mydatabase.db";
        String sql = "SELECT id, name, email FROM users";
        try (Connection conn = DriverManager.getConnection(url);
             Statement stmt = conn.createStatement();
             ResultSet rs = stmt.executeQuery(sql)) {
            // loop through the result set
            while (rs.next()) {
                System.out.println(rs.getInt("id") +  "\t" +
                                   rs.getString("name") + "\t" +
                                   rs.getString("email"));
            }
        } catch (SQLException e) {
            System.out.println(e.getMessage());
        }
    }
}

Explanation:

  • conn.createStatement() creates a Statement object for sending SQL statements to the database.
  • stmt.executeQuery(sql) executes a given SQL query, which may return multiple results. It returns a ResultSet object.
  • rs.next() moves the cursor to the next row of the ResultSet. It returns false when there are no more rows.
  • rs.getInt("column_name") and rs.getString("column_name") retrieve the value from the current row by its column name.

Update (UPDATE)

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
public class UpdateSQLiteDB {
    public static void main(String[] args) {
        String url = "jdbc:sqlite:mydatabase.db";
        // SQL update statement
        String sql = "UPDATE users SET email = 'alice_new@example.com' WHERE name = 'Alice'";
        try (Connection conn = DriverManager.getConnection(url);
             Statement stmt = conn.createStatement()) {
            int rowsAffected = stmt.executeUpdate(sql);
            System.out.println(rowsAffected + " row(s) updated.");
        } catch (SQLException e) {
            System.out.println(e.getMessage());
        }
    }
}

Explanation:

  • stmt.executeUpdate(sql) is used for SQL statements that don't return a result set, such as INSERT, UPDATE, DELETE, or DDL statements (like CREATE TABLE).
  • It returns an integer representing the number of rows affected.

Delete (DELETE)

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
public class DeleteSQLiteDB {
    public static void main(String[] args) {
        String url = "jdbc:sqlite:mydatabase.db";
        // SQL delete statement
        String sql = "DELETE FROM users WHERE name = 'Bob'";
        try (Connection conn = DriverManager.getConnection(url);
             Statement stmt = conn.createStatement()) {
            int rowsAffected = stmt.executeUpdate(sql);
            System.out.println(rowsAffected + " row(s) deleted.");
        } catch (SQLException e) {
            System.out.println(e.getMessage());
        }
    }
}

Best Practices: Using PreparedStatement

For queries that take parameters, you should always use PreparedStatement. It provides two major benefits:

  1. Security: It prevents SQL injection attacks.
  2. Performance: The database can pre-compile the query and cache it, leading to faster execution for repeated calls.

Example: Safe Insert with PreparedStatement

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class PreparedStatementExample {
    public static void main(String[] args) {
        String url = "jdbc:sqlite:mydatabase.db";
        String sql = "INSERT INTO users(name, email) VALUES(?, ?)";
        try (Connection conn = DriverManager.getConnection(url);
             PreparedStatement pstmt = conn.prepareStatement(sql)) {
            // Set the parameters for the first user
            pstmt.setString(1, "Charlie");
            pstmt.setString(2, "charlie@example.com");
            pstmt.executeUpdate();
            // Set the parameters for the second user and reuse the statement
            pstmt.setString(1, "Diana");
            pstmt.setString(2, "diana@example.com");
            pstmt.executeUpdate();
            System.out.println("Two users inserted successfully.");
        } catch (SQLException e) {
            System.out.println(e.getMessage());
        }
    }
}

Explanation:

  • The are placeholders for parameters.
  • pstmt.setString(1, "value") sets the first placeholder () to the given string value.
  • You can reuse the same PreparedStatement object with different parameter values, which is very efficient.

Transactions

By default, SQLite runs in auto-commit mode, meaning each statement is its own transaction. For data integrity, you often want to group multiple operations into a single transaction. If any part of the transaction fails, the entire transaction is rolled back.

Example: Transaction with Rollback

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
public class TransactionExample {
    public static void main(String[] args) {
        String url = "jdbc:sqlite:mydatabase.db";
        String sql1 = "INSERT INTO users(name, email) VALUES('Eve', 'eve@example.com')";
        String sql2 = "INSERT INTO users(name, email) VALUES('Frank', 'frank@example.com')";
        Connection conn = null;
        try {
            conn = DriverManager.getConnection(url);
            // Disable auto-commit mode
            conn.setAutoCommit(false);
            Statement stmt = conn.createStatement();
            stmt.execute(sql1);
            stmt.execute(sql2);
            // Commit the transaction if all statements succeed
            conn.commit();
            System.out.println("Transaction committed successfully.");
        } catch (SQLException e) {
            System.out.println("Transaction failed. Rolling back...");
            try {
                if (conn != null) {
                    conn.rollback(); // Roll back the transaction
                }
            } catch (SQLException ex) {
                System.out.println(ex.getMessage());
            }
            System.out.println(e.getMessage());
        } finally {
            try {
                if (conn != null) {
                    conn.close(); // Re-enable auto-commit and close
                }
            } catch (SQLException e) {
                System.out.println(e.getMessage());
            }
        }
    }
}

Explanation:

  • conn.setAutoCommit(false) disables the default auto-commit behavior.
  • conn.commit() saves all changes made during the transaction.
  • conn.rollback() undoes all changes made during the transaction.
  • It's crucial to reset auto-commit to true (or simply close the connection) in a finally block to ensure the connection is returned to its normal state.
分享:
扫描分享到社交APP
上一篇
下一篇