2.1 Giới thiệu về các lớp Truy vấn

Nhân tiện, một điểm quan trọng khác là lớp Trình trợ giúp truy vấn. Bạn có thể thấy nó trong ví dụ này:

public List<Employee> getAllEmployes() {
    try (Session session = sessionFactory.openSession()) {
            Query<Employee> query = session.createQuery("from Employee", Employee.class);
            return query.list();
    }
}

Trên thực tế, Truy vấn là một giao diện và nó có một số triển khai cho các trường hợp khác nhau. Nhưng để đơn giản, tôi sẽ tiếp tục gọi nó là một lớp. Giả sử đây là một lớp theo nghĩa rộng - theo OOP.

Ghi chú. Đã từng có hai lớp:

  • Truy vấn để mô tả truy vấn.
  • TypedQuery để mô tả truy vấn có loại đã biết.

Lần đầu tiên xuất hiện khi Hibernate đã tồn tại và chưa có thuốc generic. Sau đó, sau khi phát hành JDK 5, một lớp khác đã được thêm vào Hibernate - TypedQuery, lớp này đã hỗ trợ việc nhập kết quả truy vấn.

Tuy nhiên, theo như tôi nhớ, bắt đầu từ phiên bản thứ 5 của Hibernate, chỉ còn lại một lớp được nhập và bây giờ nó được gọi là Truy vấn.

Cách tiêu chuẩn để tạo Truy vấn là:


Query<Employee> query = session.createQuery("from Employee", Employee.class);

Bạn đã học cách tạo các đối tượng Truy vấn, nhưng bạn thực hiện các truy vấn này như thế nào?

Nó thậm chí còn đơn giản hơn ở đây - chúng ta chỉ cần gọi phương thức list() trên đối tượng Truy vấn:


Query<Employee> query = session.createQuery("from Employee", Employee.class);
List<Employee> resultLіst = query.list();

Phương thức list() có từ đồng nghĩa JPA, một phương thức thực hiện điều tương tự nhưng được gọi là getResultList() . Đôi khi bạn có thể thấy nó trong mã được viết bởi các lập trình viên khác.

Nhân tiện, nếu truy vấn ngụ ý rằng kết quả sẽ nằm trong một kết quả duy nhất, thì việc sử dụng phương thức uniqueResult() để gọi truy vấn sẽ dễ dàng hơn .


Query<Employee> query = session.createQuery("from Employee where id = 1", Employee.class);
Employee result = query.uniqueResult();

Phương thức uniqueResult() có một từ đồng nghĩa JPA, phương thức singleResult() . Nó được giới thiệu để tương thích với Hibernate với tiêu chuẩn JPA. Anh ấy làm chính xác điều tương tự.

2.2 Các phương thức của lớp truy vấn

Trên thực tế, lớp Truy vấn có rất nhiều phương thức khác nhau. Dưới đây tôi sẽ nói về ba trong số họ.

Đầu tiên là phương thức stream() . Và từ đồng nghĩa JPA của nó getResultStream() .

Cả hai phương thức này đều trả về một luồng dữ liệu thay vì một danh sách. Cách tiếp cận này có thể rất hiệu quả khi bạn không cần tất cả các đối tượng thu được do truy vấn cùng một lúc. Hoặc có khả năng chỉ cái đầu tiên trong số chúng sẽ được sử dụng.

Ví dụ:


Query<Employee> query = session.createQuery("from Employee where id > 100", Employee.class);
Stream<Employee> stream = query.stream();

Phương thức thứ hai là phương thức execUpdate() . Bạn có thể viết một truy vấn sẽ thay đổi điều gì đó trong cơ sở dữ liệu. Trong trường hợp này, điều cần thiết là Hibernate không sử dụng giao dịch chỉ đọc khi truy cập cơ sở dữ liệu.

Ví dụ về yêu cầu: chúng tôi quyết định nâng cấp của tất cả người dùng lên 1.


Query<User> query = session.createQuery("update User set level=level+1", User.class);
int count = query.executeUpdate();

Phương thức execUpdate() sẽ trả về số hàng đã thực sự được sửa đổi.

Và cuối cùng phương pháp thứ ba là scroll() . Chúng tôi sẽ cho bạn biết thêm một chút về nó.

2.3 Các phương thức của lớp cuộn

Phương thức này hơi giống với phương thức stream() . Chỉ có nó mới cho phép bạn di chuyển qua danh sách kết quả mà không cần rút kết quả ra. Nghĩa là, bạn có thể thực hiện một truy vấn, sau đó cuộn nó đến dòng thứ một triệu của kết quả và bắt đầu đọc dữ liệu từ đó.

Như một iterator nâng cao.


Query<Employee> query = session.createQuery("from Employee where id > 100", Employee.class);
ScrollableResults<Employee> scroll = query.scroll();

Đối tượng ScrollableResults có các phương thức sau:

Phương pháp Sự miêu tả
R nhận() Trả về phần tử hiện tại
Kế tiếp() Di chuyển con trỏ đến phần tử tiếp theo
trước() Di chuyển con trỏ đến phần tử trước đó
cuộn (kích thước int) Cuộn về phía trước theo dòng kích thước
vị trí (int pos) Đặt số pos của phần tử thành phần tử hiện tại
cuối cùng() Phần tử hiện tại là phần tử cuối cùng
Đầu tiên() Phần tử hiện tại là phần tử đầu tiên
getRowNumber() Trả về số dòng hiện tại
setRowNumber() Đặt số dòng hiện tại

Giả sử bạn chạy một truy vấn và bạn muốn lấy phần tử cuối cùng. Đây là cách để làm điều đó:


Query<Employee> query = session.createQuery("from Employee where id > 100", Employee.class);
ScrollableResults<Employee> scroll = query.scroll();
scroll.last();
Employee lastEmployee = scroll.get();