Database
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Database

Lọc dữ liệu với JDBC RowSet

Đôi khi, các truy vấn ứng dụng đến cơ sở dữ liệu trả về một số lượng lớn các hàng. Mặc dù dữ liệu đã tìm nạp được lưu vào bộ nhớ đệm trong ResultSet đối tượng, nó thường quá lớn để làm việc với chúng. Do đó, chúng ta phải có thể lọc chúng trong các tập dữ liệu khác nhau để giới hạn các hàng hiển thị. Bài viết này đi sâu vào mô tả khía cạnh lọc của JDBC RowSet với các ví dụ thích hợp.

Tổng quan về RowSet

RowSet là một giao diện bổ sung cho mô hình thành phần JDBC API cho JavaBeans. Nó cung cấp một tập hợp các thuộc tính cho phép cấu hình phiên bản của nó để kết nối với nguồn dữ liệu JDBC. A RowSet instance chủ yếu được sử dụng để lấy dữ liệu từ nguồn dữ liệu. Các phương thức setter của giao diện này được sử dụng để điền các tham số của thuộc tính lệnh của truy vấn SQL, sau đó được sử dụng để tìm nạp các bản ghi từ cơ sở dữ liệu quan hệ. Bởi vì RowSet tuân theo mô hình thành phần JavaBean, nó hỗ trợ các sự kiện JavaBean. Các sự kiện này được sử dụng để thông báo cho các thành phần khác về các sự kiện, chẳng hạn như sự thay đổi giá trị trên một tập hợp hàng. Bởi vì RowSet giao diện được thiết kế như một lớp phía trên trình điều khiển JDBC, nó mở để triển khai tùy chỉnh. Quyền tự do này cho phép nhà cung cấp tạo ra hiệu ứng tinh chỉnh của riêng họ và gửi nó cùng với sản phẩm JDBC.

FilteredRowSet

FilteredRowSet là một phần mở rộng giao diện của RowSet gia đình. Có một triển khai tham chiếu của giao diện này, được gọi là FilteredRowSetImpl lớp. Để cung cấp triển khai tùy chỉnh của FilteredRowSet , một trong hai có thể mở rộng FilteredRowSetImpl hoặc sử dụng FilteredRowSet giao diện theo yêu cầu của bạn. Đôi khi, chúng tôi cần áp dụng một số hình thức lọc nội dung mà RowSet tìm nạp. Một giải pháp đơn giản có thể thực hiện là cung cấp ngôn ngữ truy vấn cho tất cả RowSet triển khai. Nhưng sau đó, đây không phải là một cách tiếp cận khả thi vì RowSet được xây dựng với ý tưởng về một thành phần nhẹ không kết nối. Điều này sẽ làm cho vật nặng và đi ngược lại nguyên tắc thiết kế của nó. Chúng tôi cần một phương pháp giải quyết nhu cầu nhưng không đưa ngôn ngữ truy vấn nặng vào cùng với logic xử lý của lọc. JDBC FilteredRowSet triển khai tiêu chuẩn mở rộng RowSet thông qua các giao diện con như CachedRowSet WebRowSet tương ứng. FilteredRowSet có thể thao tác với con trỏ thông qua tập hợp các phương pháp thao tác với con trỏ được bảo vệ do CachedRowSet cung cấp giao diện. Các phương pháp này có thể được ghi đè theo yêu cầu và trợ giúp trong khi lọc RowSet nội dung.

Một ví dụ nhanh

Dưới đây là một ví dụ để minh họa cách FilteredRowSet được sử dụng để lưu trữ nội dung được trả về bởi truy vấn được kích hoạt đến cơ sở dữ liệu. Kết quả của truy vấn được lọc theo cấu hình áp dụng cho FilteredRowset thực hiện. Điều này xác định nội dung hiển thị hoặc các hàng mà chúng tôi quan tâm từ kết quả được trả về bởi truy vấn. Trong ví dụ sau, chúng tôi đã tạo một lớp bộ lọc có tên là SimpleFilter . Trong trường hợp của chúng tôi, lớp này xác định việc triển khai tùy chỉnh của FilteredRowSet . Sau đó, chúng tôi áp dụng bộ lọc này trên kết quả trả về từ truy vấn cơ sở dữ liệu. Lọc có nghĩa là giới hạn số hàng sẽ được hiển thị. Do đó, ở đây chúng tôi sẽ giới hạn số lượng bản ghi thông tin sách theo tên tác giả đã chọn được cung cấp.

Để thực hành, sau đây là các bảng cơ sở dữ liệu được sử dụng với mã Java sắp tới.


Hình 1: Bảng cơ sở dữ liệu, sách


Hình 2: Bảng cơ sở dữ liệu, tác giả


Hình 3: Bảng cơ sở dữ liệu, book_author

Bộ lọc đơn giản lớp triển khai Vị từ Đánh giá các phương pháp để triển khai bộ lọc tùy chỉnh của chúng tôi.

package org.mano.example;
import javax.sql.RowSet;
import javax.sql.rowset.Predicate;
import java.sql.SQLException;
public class SimpleFilter implements Predicate {
   private String[] authors;
   private String colname = null;
   private int colno = -1;
   public SimpleFilter(String[] authors, String colname) {
      this.authors = authors;
      this.colno = -1;
      this.colname = colname;
   }
   public SimpleFilter(String[] authors, int colno) {
      this.authors = authors;
      this.colno = colno;
      this.colname = null;
   }
   @Override
   public Boolean evaluate(Object value, String colName) {
      if (colName.equalsIgnoreCase(this.colname)) {
         for (String author : this.authors) {
            if (author.equalsIgnoreCase((String)value)) {
              return true;
            }
         }
      }
      return false;
   }
   @Override
   public Boolean evaluate(Object value, int colNumber) {
      if (colNumber == this.colno) {
         for (String author : this.authors)
            if (author.equalsIgnoreCase((String)value)) {
               return true;
            }
         }
      }
      return false
   }
   @Override
   public Boolean evaluate(RowSet rs) {
      if (rs == null) return false;
      try {
         for (int i=0;i<authors.length;i++) {
            String al = null;
            if (this.colno> 0) {
                al = (String)rs.getObject(this.colno);
            } else if (this.colname != null) {
               al = (String)rs.getObject(this.colname);
            } else {
               return false;
            }
            if (al.equalsIgnoreCase(authors[i])) {
               return true;
            }
         }
      } catch (SQLException e) {
         return false;
      }
      return false;
   }
}

Lớp này được sử dụng để thực thi SimpleRowSet lớp lọc. Lưu ý cách chúng tôi đã sử dụng FilteredRowSet để lọc dữ liệu trong ứng dụng. Quá trình xử lý xảy ra ở cấp ứng dụng chứ không phải ở cấp cơ sở dữ liệu SQL. Do đó, chúng ta có thể triển khai một loạt các bộ lọc và áp dụng chúng trên cùng một tập kết quả để thu được kết quả mong muốn. Điều này thúc đẩy hiệu suất bởi vì chúng tôi không phải kích hoạt nhiều truy vấn đến cơ sở dữ liệu để nhận được kết quả sửa đổi. Thay vào đó, chúng tôi có thể áp dụng nhiều lọc trên kết quả truy vấn được kích hoạt một lần vào cơ sở dữ liệu. Ứng dụng có hai giai đoạn quan trọng:

  • Chúng tôi tạo một bộ lọc đưa ra các tiêu chí để lọc dữ liệu. Điều này được thực hiện bằng cách triển khai Vị từ giao diện. Có thể có nhiều hàm tạo chấp nhận các tập đối số khác nhau. Ngoài ra, bộ lọc có thể chứa một mảng đánh giá () các phương thức cũng chấp nhận các tập hợp đối số khác nhau với tập hợp triển khai riêng biệt của chúng.
  • FilteredRowSet lớp phải được khởi tạo để có được hiệu ứng mong muốn, điều mà chúng tôi đã thực hiện ở đây với applyFilter () phương pháp. FilteredRowSet sử dụng lớp bộ lọc tùy chỉnh mà chúng tôi đã cung cấp để xác định các bản ghi sẽ được xem.
package org.mano.example;
import com.sun.rowset.FilteredRowSetImpl;
import javax.sql.RowSet;
import javax.sql.rowset.FilteredRowSet;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class DemoApp {
   private static final String DB_URL =
      "jdbc:mysql://localhost:3306/my_lib";
   private static final String DB_DRIVER =
      "com.mysql.cj.jdbc.Driver";
   private static final String DB_USERNAME =
      "root";
   private static final String DB_PASSWORD =
      "secret";
   public static Connection conn = null;
   public static FilteredRowSet filteredRowSet = null;
   public static void main(String[] args) {
      try {
         Class.forName(DB_DRIVER);
         conn = DriverManager.getConnection(DB_URL,
            DB_USERNAME,DB_PASSWORD);
         System.out.println("Database connection
            successful.");
         applyFilter();
      } catch (SQLException | ClassNotFoundException ex) {
         System.out.println(ex);
      } finally {
         if (conn != null) {
            try {
               conn.close();
            catch (SQLException ex) {
               ex.printStackTrace();
            }
         }
         if (filteredRowSet != null) {
            try {
               filteredRowSet.close();
            } catch (SQLException ex) {
               ex.printStackTrace();
            }
         }
      }
   }
   public static void applyFilter() {
      String[] arr = {"Donne", "Milton"};
      SimpleFilter aFilter = new SimpleFilter(arr, 3);
      try {
         filteredRowSet = new FilteredRowSetImpl();
         filteredRowSet.setCommand("SELECT title, f_name, l_name "
            + "FROM book_author BA, "
            + "author A, "
            + "book B "
            + "WHERE A.auth_id = BA.fk_author "
            + "AND B.book_id = BA.fk_book");
            filteredRowSet.execute(conn);
            System.out.println
               ("--------------------------------------------");
            System.out.println("Before applying any
               filter:");
            System.out.println
               ("--------------------------------------------");
            show(filteredRowSet);
            System.out.println
               ("--------------------------------------------");
            System.out.println("After applying
               filter :");
            System.out.println
               ("--------------------------------------------");
            filteredRowSet.beforeFirst();
            filteredRowSet.setFilter(aFilter);
            show(filteredRowSet);
      } catch (SQLException e) {
         e.printStackTrace();
      }
   }
   public static void show(RowSet rs) {
      try {
         while (rs.next()) {
            System.out.println(rs.getString(1) + " / "
               + rs.getString(2)
               + " "+rs.getString(3));
         }
      } catch (SQLException ex) {
         ex.printStackTrace();
      }
   }
}

Đầu ra

Database connection successful.
--------------------------------------------
Before applying any filter:
--------------------------------------------
Gulliver's Travels / Jonathan Swift

...

Ill Pensoroso / John Milton
Areopagitica / John Milton
--------------------------------------------
After applying filter:
--------------------------------------------
The Flea / John Donne
Holy Sonnet / John Donne
Paradise Lost / John Milton
Paradise Regained / John Milton
Ill Pensoroso / John Milton
Areopagitica / John Milton

Kết luận

Làm việc với một số lượng lớn các hàng được trả về từ một truy vấn có nhiều vấn đề. Đối với một, dữ liệu được truy xuất chiếm bộ nhớ.

Nó luôn giúp giới hạn chúng tùy theo nhu cầu và mức độ phù hợp. Với RowSet , chúng tôi có thể lọc chúng theo một tiêu chí mà không cần thực hiện bất kỳ yêu cầu cơ sở dữ liệu bổ sung nào. Điều này giúp dễ quản lý hơn khi làm việc với các hàng cơ sở dữ liệu và thúc đẩy hiệu quả của mã.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Toán tử CHỌN VÀ SQL

  2. Mối quan hệ một-một trong cơ sở dữ liệu là gì?

  3. Toán tử so sánh là gì?

  4. Tạo một tập hợp hoặc trình tự không có vòng lặp - phần 2

  5. Cách phân nhóm theo năm trong T-SQL