Bài viết Câu hỏi About RongvangIT
profile Pic
0
0

Đăng ngày:

  49 Lượt xem

Kết nối từ Java đến PostgreSQL

JDBCJavaPostgreSQL

Chào anh em.
Gần đây, tôi có nhiều cơ hội kết nối đến PostgreSQL từ các chương trình khác nhau, vì vậy tôi đã tổng hợp các bước. Vì có vẻ sẽ dài, nên lần này tôi sẽ thử kết nối từ Java đến PostgreSQL trước và chia sẻ cho anh em nhé.

Kết nối từ Java đến PostgreSQL

  • Thông tin môi trường
    H điu hành: Windows 10
    PostgreSQL: 10.1
    Java: 1.8
    JDBC: 4.2

Giả định rằng môi trường PostgreSQL và Java đã được cài đặt. Đầu tiên, để kết nối từ Java đến PostgreSQL, bạn cần lấy trình điều khiển JDBC của PostgreSQL.

Sau đó, nếu bạn sử dụng Eclipse, nhấp chuột phải vào dự án bạn sẽ tạo trong Trình duyệt Gói và chọn “Build Path” -> “Configure Build Path”. Sau đó, chọn tab “Libraries” và nhấp vào “Add External JARs”, sau đó thêm trình điều khiển JDBC PostgreSQL bạn đã tải xuống. Sau đó, bạn có thể viết mã sau để kết nối đến PostgreSQL.
Trong ví dụ này, chúng ta sẽ thực thi một transaction SELECT và INSERT như làm thử nghiệm.

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

public class Sample_pos_conn {
    public static void main(String[] args) {
        Connection conn = null;
        Statement stmt = null;
        ResultSet rset = null;

        // Chuỗi kết nối
        String url = "jdbc:postgresql://123.45.67.89:5432/postgres";
        String user = "postgres";
        String password = "password";

        try{
            // Kết nối đến PostgreSQL
            conn = DriverManager.getConnection(url, user, password);

            // Tắt tự động commit
            conn.setAutoCommit(false);

            // thực thi câu lệnh SELECT
            stmt = conn.createStatement();
            String sql = "SELECT 1";
            rset = stmt.executeQuery(sql);

            // Nhận kết quả SELECT
            while(rset.next()){
                String col = rset.getString(1);
                System.out.println(col);
            }

            // thực thi câu lệnh INSERT
            sql = "INSERT INTO jdbc_test VALUES (1, 'AAA')";
            stmt.executeUpdate(sql);
            conn.commit();
        }
        catch (SQLException e){
            e.printStackTrace();
        }
        finally {
            try {
                if(rset != null)rset.close();
                if(stmt != null)stmt.close();
                if(conn != null)conn.close();
            }
            catch (SQLException e){
                e.printStackTrace();
            }

        }
    }
}

Chúng ta sẽ giải thích từng phần của đoạn mã trên một cách tuần tự.

Kết nối đến PostgreSQL

Chúng ta cần chỉ định cơ sở dữ liệu đích của chúng ta khi kết nối. Điều này đang xảy ra khi kết nối đến PostgreSQL (vì chuỗi chứa “postgres” rõ ràng). Vì vậy, nếu bạn kết nối đến cơ sở dữ liệu khác, chuỗi sẽ khác nhau. Ngược lại, nếu bạn thay đổi chuỗi kết nối, các hành vi và khả năng của JDBC sẽ giống nhau nếu bạn làm việc với cùng một hệ quản trị cơ sở dữ liệu.

Chuỗi kết nối

String url = "jdbc:postgresql://<IP hoặc tên máy chủ DB đích>:<Số cổng DB>/<Tên DB>";

Đây là thông tin của PostgreSQL mục tiêu cần kết nối. Trong ví dụ này, tôi giả định rằng bạn sẽ cung cấp thông tin này tương ứng với môi trường của bạn. Để biết ví dụ cụ thể, hãy xem mã nguồn mẫu đầu tiên.

Thực thi câu lệnh SQL

Khi thực thi SQL trong Java, có hai cách: “Statement” và “PreparedStatement”. “Statement” thực thi chuỗi đầu vào như làm và là phương pháp đơn giản. “PreparedStatement” đã được biên soạn trước và tăng tốc, và có thể thay đổi tham số sau đó, đây là một phương pháp xuất sắc. Nếu bạn sử dụng cùng một SQL nhiều lần, bạn thường sẽ sử dụng “PreparedStatement”. Tuy nhiên, trong ví dụ này, chúng ta sử dụng “Statement” đơn giản.

Câu lệnh SELECT

Statement stmt = conn.createStatement();

String sql = "SELECT 1";
rset = stmt.executeQuery(sql);

// Nhận kết quả SELECT
while(rset.next()){
    String col = rset.getString(1);
    System.out.println(col);
}

Để thực thi câu lệnh SQL, chúng ta sẽ khởi tạo “Statement” bằng cách gọi phương thức “createStatement”. Mặc dù nó giống nhau, cách bạn truyền đối số vào phương thức “createStatement” sẽ ảnh hưởng đến cách bạn nhận kết quả của SELECT. Dưới đây là một giải thích đơn giản, nhưng trong trường hợp sử dụng thông thường, bạn chỉ cần sử dụng giá trị mặc định mà không cần chỉ định đối số.

Đối số thứ nhất Mô tả
ResultSet.TYPE_FORWARD_ONLY Giá trị mặc định.
Con trỏ chỉ có thể di chuyển theo hướng chuyển tiếp.
Bạn không thể sử dụng last(), first(), v.v. của ResultSet.
ResultSet.TYPE_SCROLL_SENSITIVE Con trỏ có thể di chuyển theo hướng chuyển tiếp và ngược lại.
Sau khi nhận dữ liệu, nó không phản ánh dữ liệu đã được thay đổi bởi các kết nối khác.
ResultSet.TYPE_SCROLL_INSENSITIVE Con trỏ có thể di chuyển theo hướng chuyển tiếp và ngược lại.
Sau khi nhận dữ liệu, nó phản ánh dữ liệu đã được thay đổi bởi các kết nối khác.
Không đảm bảo tính nhất quán đọc.


Đối số thứ hai Mô tả
ResultSet.CONCUR_READ_ONLY Giá trị mặc định.
Không thể cập nhật thông qua ResultSet.
ResultSet.CONCUR_UPDATABLE Có thể cập nhật thông qua ResultSet.
Bạn có thể sử dụng các phương thức như updateXXX().

Kết quả của câu lệnh SELECT được nhận thông qua lớp “ResultSet”. Theo cách cơ bản, bạn sẽ sử dụng phương thức “next()” để truy cập dữ liệu nhận được theo hướng chuyển tiếp. Khi bạn chạy phương thức “next()” sau khi đã nhận tất cả dữ liệu, kết quả sẽ là null, vì vậy bạn sẽ lặp qua tất cả các mục bằng vòng lặp while.

Câu lệnh DML(INSERT, DELETE, UPDATE, SELECT )

Câu lệnh INSERT

// thực thi câu lệnh INSERT
sql = "INSERT INTO jdbc_test VALUES (1, 'AAA')";
stmt.executeUpdate(sql);
conn.commit();

Khác với SELECT, các lệnh DML (INSERT, DELETE, UPDATE) không nhận kết quả, vì vậy chúng ta không sử dụng ResultSet. Do đó, khi sử dụng “createStatement” để thực thi, không cần chỉ định đối số. Tuy nhiên, bạn phải sử dụng phương thức “executeUpdate()” để thực thi câu lệnh SQL. Ngoài ra, nếu bạn đã tắt tự động commit, bạn cần gọi phương thức “commit()” để xác nhận transaction.

Câu lệnh DDL (CREATE, ALTER , DROP, TRUNCATE )

Trong ví dụ này, chúng tôi không đưa ra ví dụ về lệnh DDL, nhưng nó có thể được thực thi theo cách giống nhau với lệnh DML. Đối với PostgreSQL, lệnh DDL không được thực thi mặc định, vì vậy nếu tự động commit bị tắt, bạn cũng cần xác nhận rõ ràng, tương tự như lệnh DML.

// thực thi lệnh CREATE
sql = "CREATE TABLE hoge (col1 integer)";
stmt.executeUpdate(sql);
conn.commit();

COMMIT, ROLLBACK

Như đã đề cập trước đó, COMMIT và ROLLBACK có thể được thực thi bằng cách sử dụng các phương thức. Do đó, không cần phải viết các lệnh SQL khác nhau như trước đây.

// thực thi COMMIT
conn.commit();
// thực thi ROLLBACK
conn.rollback();

Transaction

Tự động Commit

Trong JDBC, tự động commit mặc định được bật (ON). Đối với những người sử dụng PostgreSQL, điều này không gây vấn đề, nhưng cần lưu ý khi sử dụng RDBMS khác. Lưu ý rằng PostgreSQL cũng mặc định tự động commit là ON.

Để bật/tắt tự động commit, sử dụng phương thức setAutoCommit(). Khi giá trị là true, tự động commit được bật (mặc định), khi là false, tự động commit được tắt.

// Tắt tự động commit
conn.setAutoCommit(false);

Trong Java, việc tắt tự động commit thường được thực thi khi xử lý transaction. Việc nhập BEGIN trong câu lệnh SQL hiếm khi được thực thi vì lý do sẽ được mô tả sau.

Xử lý transaction khi tự động commit được tắt

Khi tự động commit được tắt, JDBC sẽ tự động nhập BEGIN khi bắt đầu câu lệnh SQL. Do đó, nếu viết rõ BEGIN như sau, có thể dẫn đến việc thực thi hai lần BEGIN trong cơ sở dữ liệu. COMMIT và ROLLBACK cũng được xử lý thông qua các hàm như đã mô tả trước đó, do đó, khi thực thi xử lý transaction trong Java, hiếm khi cần nhập các câu lệnh SQL liên quan đến transaction.

// thực thi câu lệnh BEGIN
stmt = conn.createStatement();
String sql = "BEGIN";
rset = stmt.executeQuery(sql);
LOG:  execute <unnamed>: BEGIN
LOG:  execute <unnamed>: BEGIN
WARNING:  there is already a transaction in progress

※ Đã cài đặt tham số log_statement = ‘all’ trong PostgreSQL.

Bổ sung: Về việc load JDBC Driver

Trước phiên bản JDBC 4.0, việc load rõ ràng JDBC Driver thông qua Class.forName là cần thiết.

try {
    Class.forName("org.postgresql.Driver");
    
} catch (ClassNotFoundException e) {
    
}

Câu lệnh trên có thể thay đổi tùy thuộc vào loại JDBC Driver. Nếu sử dụng cách này, bạn cần xử lý ngoại lệ ClassNotFoundException.

Tuy nhiên, từ JDBC 4.0 trở đi (=Java 1.6 trở đi), việc này được thực thi tự động, không cần phải load thủ công như trước.

In previous versions of JDBC, to obtain a connection, you first had to initialize your JDBC driver by calling the method Class.forName. This methods required an object of type java.sql.Driver. Each JDBC driver contains one or more classes that implements the interface java.sql.Driver. The drivers for Java DB are org.apache.derby.jdbc.EmbeddedDriver and org.apache.derby.jdbc.ClientDriver, and the one for MySQL Connector/J is com.mysql.jdbc.Driver. See the documentation of your DBMS driver to obtain the name of the class that implements the interface java.sql.Driver.
Any JDBC 4.0 drivers that are found in your class path are automatically loaded. (However, you must manually load any drivers prior to JDBC 4.0 with the method Class.forName.)


[Dịch bằng Google]
Trong các phiên bản trước của JDBC, để có được kết nối, bạn đầu tiên phải khởi tạo JDBC driver của mình bằng cách gọi phương thức Class.forName. Phương pháp này yêu cầu một đối tượng của loại java.sql.Driver. Mỗi driver JDBC chứa một hoặc nhiều lớp triển khai giao diện java.sql.Driver. Các driver cho Java DB là org.apache.derby.jdbc.EmbeddedDriver và org.apache.derby.jdbc.ClientDriver, và driver cho MySQL Connector/J là com.mysql.jdbc.Driver. Hãy xem tài liệu của driver DBMS của bạn để lấy tên của lớp triển khai giao diện java.sql.Driver.

Bất kỳ driver JDBC 4.0 nào được tìm thấy trong đường dẫn của bạn sẽ tự động được tải. (Tuy nhiên, bạn phải tải bằng tay bất kỳ driver nào trước JDBC 4.0 bằng phương thức Class.forName.)

Tham khảo

Bình luận

Bài viết chưa có bình luận. Hãy trở thành người bình luận đầu tiên!
Sign up for free and join this conversation.
Sign Up
If you already have a RongvangIT account Login
Danh sách thư mục
Bắt đầu ngay với RồngVàngIT - nền tảng chia sẻ kiến thức lập trình tuyệt vời cho kỹ sư Việt Nam!

Hãy đăng nhập để sử dụng hàng loạt các chức năng tuyệt vời của RồngVàngIT !

  1. 1. Bạn sẽ nhận được các bài viết phù hợp bằng chức năng theo dõi tag và người dùng.
  2. 2. Bạn có thể đọc lại các thông tin hữu ích bằng chức năng lưu trữ nội dung.
  3. 3. Chia sẻ kiến thức, đặt câu hỏi và ghi lại quá trình trưởng thành của mình cùng RồngVàngIT !
Tạo tài khoản Đăng nhập
profile Pic