0

Apache Derby Bài 22: Kết nối từ xa bằng ClientDriver (derbyclient.jar)

1. Sự chuyển đổi từ Embedded sang Client-Server

Ở Bài 21, chúng ta đã khởi động thành công Derby Network Server. Lúc này, Derby đóng vai trò là một máy chủ (Server) thực thụ, đang mở cổng TCP/IP và chờ đợi các yêu cầu.

Ứng dụng Java của bạn bây giờ không còn "ôm" cơ sở dữ liệu vào trong bộ nhớ của chính nó nữa, mà sẽ đóng vai trò là một Máy khách (Client). Để làm được điều này, chúng ta phải thay đổi hai yếu tố cốt lõi trong mã nguồn:

  1. Đổi thư viện sử dụng (từ lõi Engine sang thư viện Client).

  2. Đổi chuỗi định tuyến JDBC URL (bổ sung thêm địa chỉ IP và cổng mạng).

2. Cấu hình thư viện Maven/Gradle cho Client

Trong chế độ kết nối mạng, ứng dụng Java của bạn không cần và không nên tải thư viện lõi derby.jar (nặng ~3.5MB). Thay vào đó, bạn chỉ cần tải một thư viện rất nhẹ chứa các giao thức truyền tải mạng mang tên derbyclient.jar (nặng ~600KB).

Nếu dùng Maven (pom.xml):

XML

<dependencies>
    <dependency>
        <groupId>org.apache.derby</groupId>
        <artifactId>derbyclient</artifactId>
        <version>10.17.1.0</version>
    </dependency>
</dependencies>

Nếu dùng Gradle (build.gradle):

Groovy

dependencies {
    implementation 'org.apache.derby:derbyclient:10.17.1.0'
}

3. Cú pháp JDBC URL cho kết nối mạng

Vì cơ sở dữ liệu giờ đây nằm trên một máy chủ khác (hoặc một tiến trình khác trên cùng máy), chuỗi kết nối của bạn phải chỉ định rõ vị trí của máy chủ đó.

Cú pháp tổng quát:

Plaintext

jdbc:derby://<server>:<port>/<databaseName>[;attribute=value]

  • <server>: Tên miền hoặc địa chỉ IP của máy chủ đang chạy Derby (ví dụ: localhost, 192.168.1.100).

  • <port>: Cổng mạng mà máy chủ đang lắng nghe (mặc định là 1527).

  • <databaseName>: Tên thư mục cơ sở dữ liệu trên máy chủ.

  • Các thuộc tính (;create=true, user=...) vẫn hoạt động y hệt như chế độ Embedded.

Ví dụ thực tế:

SQL

-- Kết nối đến máy chủ cài trên chính máy tính đang chạy code
jdbc:derby://localhost:1527/quan_ly_kho;create=true

-- Kết nối đến máy chủ trong mạng LAN nội bộ công ty
jdbc:derby://192.168.1.50:1527/nhan_su_db

4. Lớp điều khiển ClientDriver

Nếu như ở chế độ nhúng (Bài 15) chúng ta sử dụng org.apache.derby.jdbc.EmbeddedDriver, thì ở chế độ mạng, hệ thống sử dụng lớp:

org.apache.derby.jdbc.ClientDriver

Cũng giống như các phiên bản JDBC hiện đại (từ JDBC 4.0 trở đi), lớp DriverManager sẽ tự động quét và nạp Driver này vào bộ nhớ thông qua cơ chế SPI miễn là bạn đã thêm dependency derbyclient vào dự án. Bạn không cần phải gọi hàm Class.forName() thủ công.

5. Thực hành: Viết mã nguồn Client kết nối tới Server

Yêu cầu chuẩn bị: Trước khi chạy đoạn mã dưới đây, bạn bắt buộc phải mở Terminal và chạy lệnh startNetworkServer (như đã học ở Bài 21) để máy chủ sẵn sàng đón nhận kết nối.

Tạo một class Java mới và thực thi mã sau:

Java

package com.hieu.derby.client;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class DerbyNetworkClientDemo {

    // Chuỗi kết nối chỉ định giao thức mạng: //localhost:1527/
    private static final String NETWORK_JDBC_URL = 
            "jdbc:derby://localhost:1527/network_test_db;create=true";

    public static void main(String[] args) {
        System.out.println("Đang gửi yêu cầu kết nối tới Derby Network Server...");

        // Khởi tạo kết nối qua mạng TCP/IP
        try (Connection conn = DriverManager.getConnection(NETWORK_JDBC_URL)) {
            System.out.println("=> Kết nối TCP/IP thành công!");

            // Thử nghiệm tạo bảng qua mạng
            try (Statement stmt = conn.createStatement()) {
                String createTable = "CREATE TABLE log_he_thong (id INT PRIMARY KEY, thong_diep VARCHAR(200))";
                stmt.executeUpdate(createTable);
                System.out.println("=> Tạo bảng 'log_he_thong' trên Server thành công.");
            } catch (SQLException e) {
                if ("X0Y32".equals(e.getSQLState())) {
                    System.out.println("=> Bảng đã tồn tại trên Server.");
                } else {
                    throw e;
                }
            }

            // Thực thi truy vấn qua mạng
            String insertSql = "INSERT INTO log_he_thong VALUES (1, 'Client vừa kết nối vào lúc 10:00')";
            try (PreparedStatement pstmt = conn.prepareStatement(insertSql)) {
                pstmt.executeUpdate();
                System.out.println("=> Chèn dữ liệu từ xa thành công!");
            }

        } catch (SQLException e) {
            // Lỗi phổ biến nhất ở đây là 08001: Không thể kết nối tới Server (Do quên bật Server)
            System.err.println("Lỗi mạng / CSDL: SQLState = " + e.getSQLState());
            System.err.println("Chi tiết: " + e.getMessage());
        }
    }
}

Phân tích lỗi 08001 (Connection refused)

Nếu bạn chạy đoạn mã trên mà chưa khởi động máy chủ, chương trình sẽ khựng lại một lúc (do Timeout mạng) và văng ra lỗi:

Plaintext

Lỗi mạng / CSDL: SQLState = 08001
Chi tiết: java.net.ConnectException : Error connecting to server localhost on port 1527 with message Connection refused.

Đây là tín hiệu rõ ràng nhất cho thấy ứng dụng của bạn không thể tìm thấy máy chủ ở IP/Cổng đã cấu hình. Hãy kiểm tra lại Terminal chạy Server hoặc tường lửa (Firewall) của Windows/Linux.

6. Tổng kết

  • Để kết nối từ xa, ứng dụng Java thay đổi dependency từ derby sang derbyclient.

  • URL thay đổi thêm phần //host:port/ để định tuyến mạng.

  • Mã nguồn xử lý câu lệnh SQL (như Statement, PreparedStatement, ResultSet) giữ nguyên 100%. Bạn không cần sửa đổi bất kỳ logic nghiệp vụ truy vấn nào khi chuyển đổi từ ứng dụng Embedded sang ứng dụng Network Client. Đó là sự thiết kế tuyệt vời của tiêu chuẩn JDBC.

Trong thực tế doanh nghiệp, việc để server chạy mặc định ở localhost là không đủ. Ở bài tiếp theo, chúng ta sẽ đi sâu vào cấu hình máy chủ: Apache Derby Bài 23: Cấu hình cổng kết nối, địa chỉ máy chủ và tùy chọn logging.


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí