Đánh giá truy vấn sql block access năm 2024

Khi sử dụng thư viện Room về dữ liệu cố định để lưu trữ dữ liệu của ứng dụng, bạn sẽ tương tác với dữ liệu được lưu trữ bằng cách xác định các đối tượng truy cập dữ liệu hay còn gọi là DAO. Mỗi DAO có các phương thức cung cấp quyền truy cập trừu tượng vào cơ sở dữ liệu của ứng dụng. Vào thời gian biên dịch, Room sẽ tự động tạo hoạt động triển khai các DAO mà bạn xác định.

Bằng cách sử dụng DAO để truy cập cơ sở dữ liệu của ứng dụng thay vì các trình tạo truy vấn hoặc truy vấn trực tiếp, bạn có thể duy trì – một nguyên tắc kiến trúc quan trọng. Các DAO cũng giúp bạn dễ dàng mô phỏng quyền truy cập cơ sở dữ liệu khi kiểm thử ứng dụng của bạn.

Phân tích thành phần của DAO

Bạn có thể xác định mỗi DAO là giao diện hoặc lớp trừu tượng. Đối với các trường hợp sử dụng cơ bản, bạn thường sử dụng giao diện. Trong cả hai trường hợp, bạn phải luôn chú giải các DAO của mình bằng

@Dao public interface UserDao {

@Insert(onConflict = OnConflictStrategy.REPLACE)
public void insertUsers(User... users);
@Insert
public void insertBothUsers(User user1, User user2);
@Insert
public void insertUsersAndFriends(User user, List friends);
}

4. Các DAO không có thuộc tính nhưng lại xác định một hoặc nhiều phương thức tương tác với dữ liệu trong cơ sở dữ liệu của ứng dụng.

Mã sau đây là ví dụ về một DAO đơn giản xác định các phương thức chèn, xoá và chọn đối tượng

@Dao public interface UserDao {

@Insert(onConflict = OnConflictStrategy.REPLACE)
public void insertUsers(User... users);
@Insert
public void insertBothUsers(User user1, User user2);
@Insert
public void insertUsersAndFriends(User user, List friends);
}

5 trong cơ sở dữ liệu Room:

Kotlin

@Dao interface UserDao {

@Insert
fun insertAll(vararg users: User)
@Delete
fun delete(user: User)
@Query("SELECT * FROM user")
fun getAll(): List
}

Java

@Dao public interface UserDao {

@Insert
void insertAll(User... users);
@Delete
void delete(User user);
@Query("SELECT * FROM user")
List getAll();
}

Có hai loại phương thức DAO để xác định các hoạt động tương tác với cơ sở dữ liệu:

  • Các phương thức thuận tiện cho phép bạn chèn, cập nhật và xoá hàng trong cơ sở dữ liệu mà không cần ghi bất kỳ mã SQL nào.
  • Các phương thức truy vấn cho phép bạn ghi truy vấn SQL của riêng bạn để tương tác với cơ sở dữ liệu.

Các mục sau đây minh hoạ cách sử dụng cả hai loại phương thức DAO để xác định các hoạt động tương tác với cơ sở dữ liệu mà ứng dụng của bạn cần.

Phương thức thuận tiện

Room cung cấp các chú giải thuận tiện để xác định các phương thức thực hiện thao tác chèn, cập nhật và xoá đơn giản mà không yêu cầu bạn ghi câu lệnh SQL.

Nếu bạn cần xác định các thao tác chèn, cập nhật hoặc xoá phức tạp hơn hoặc cần truy vấn dữ liệu trong cơ sở dữ liệu, hãy sử dụng .

Chèn

Chú giải

@Dao public interface UserDao {

@Insert(onConflict = OnConflictStrategy.REPLACE)
public void insertUsers(User... users);
@Insert
public void insertBothUsers(User user1, User user2);
@Insert
public void insertUsersAndFriends(User user, List friends);
}

6 cho phép bạn xác định các phương thức có thể chèn tham số của chúng vào bảng thích hợp trong cơ sở dữ liệu. Đoạn mã sau đây cho thấy ví dụ về các phương thức

@Dao public interface UserDao {

@Insert(onConflict = OnConflictStrategy.REPLACE)
public void insertUsers(User... users);
@Insert
public void insertBothUsers(User user1, User user2);
@Insert
public void insertUsersAndFriends(User user, List friends);
}

6 hợp lệ có tác dụng chèn một hoặc nhiều đối tượng

@Dao public interface UserDao {

@Insert(onConflict = OnConflictStrategy.REPLACE)
public void insertUsers(User... users);
@Insert
public void insertBothUsers(User user1, User user2);
@Insert
public void insertUsersAndFriends(User user, List friends);
}

5 vào cơ sở dữ liệu:

Kotlin

@Dao interface UserDao {

@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insertUsers(vararg users: User)
@Insert
fun insertBothUsers(user1: User, user2: User)
@Insert
fun insertUsersAndFriends(user: User, friends: List)
}

Java

@Dao public interface UserDao {

@Insert(onConflict = OnConflictStrategy.REPLACE)
public void insertUsers(User... users);
@Insert
public void insertBothUsers(User user1, User user2);
@Insert
public void insertUsersAndFriends(User user, List friends);
}

Mỗi tham số cho một phương thức

@Dao public interface UserDao {

@Insert(onConflict = OnConflictStrategy.REPLACE)
public void insertUsers(User... users);
@Insert
public void insertBothUsers(User user1, User user2);
@Insert
public void insertUsersAndFriends(User user, List friends);
}

6 phải là một phiên bản của lớp thực thể dữ liệu Room được chú giải bằng

@Dao interface UserDao {

@Update
fun updateUsers(vararg users: User)
}

0 hoặc một tập hợp các phiên bản lớp thực thể dữ liệu, mỗi phiên bản trỏ đến một cơ sở dữ liệu. Khi một phương thức

@Dao public interface UserDao {

@Insert(onConflict = OnConflictStrategy.REPLACE)
public void insertUsers(User... users);
@Insert
public void insertBothUsers(User user1, User user2);
@Insert
public void insertUsersAndFriends(User user, List friends);
}

6 được gọi, Room sẽ chèn từng phiên bản thực thể đã truyền vào bảng cơ sở dữ liệu tương ứng.

Nếu nhận được một tham số duy nhất, thì phương thức

@Dao public interface UserDao {

@Insert(onConflict = OnConflictStrategy.REPLACE)
public void insertUsers(User... users);
@Insert
public void insertBothUsers(User user1, User user2);
@Insert
public void insertUsersAndFriends(User user, List friends);
}

6 có thể trả về một giá trị

@Dao interface UserDao {

@Update
fun updateUsers(vararg users: User)
}

3 (đây là giá trị

@Dao interface UserDao {

@Update
fun updateUsers(vararg users: User)
}

4 mới cho mục được chèn). Nếu tham số là một mảng hoặc một tập hợp, thì phương thức sẽ trả về một mảng hoặc một tập hợp các giá trị

@Dao interface UserDao {

@Update
fun updateUsers(vararg users: User)
}

3 thay thế, với mỗi giá trị là

@Dao interface UserDao {

@Update
fun updateUsers(vararg users: User)
}

4 cho một trong các mục được chèn. Để tìm hiểu thêm về việc trả về các giá trị

@Dao interface UserDao {

@Update
fun updateUsers(vararg users: User)
}

4, hãy xem tài liệu tham khảo cho chú giải

@Dao public interface UserDao {

@Insert(onConflict = OnConflictStrategy.REPLACE)
public void insertUsers(User... users);
@Insert
public void insertBothUsers(User user1, User user2);
@Insert
public void insertUsersAndFriends(User user, List friends);
}

6 và Tài liệu SQLite cho bảng rowid.

Cập nhật

Chú giải

@Dao interface UserDao {

@Update
fun updateUsers(vararg users: User)
}

9 cho phép bạn xác định các phương thức cập nhật những hàng cụ thể trong bảng cơ sở dữ liệu. Tương tự như phương thức

@Dao public interface UserDao {

@Insert(onConflict = OnConflictStrategy.REPLACE)
public void insertUsers(User... users);
@Insert
public void insertBothUsers(User user1, User user2);
@Insert
public void insertUsersAndFriends(User user, List friends);
}

6, phương thức

@Dao interface UserDao {

@Update
fun updateUsers(vararg users: User)
}

9 chấp nhận các phiên bản thực thể dữ liệu dưới dạng tham số. Đoạn mã sau đây cho thấy ví dụ về phương thức

@Dao interface UserDao {

@Update
fun updateUsers(vararg users: User)
}

9 cố gắng cập nhật một hoặc nhiều đối tượng

@Dao public interface UserDao {

@Insert(onConflict = OnConflictStrategy.REPLACE)
public void insertUsers(User... users);
@Insert
public void insertBothUsers(User user1, User user2);
@Insert
public void insertUsersAndFriends(User user, List friends);
}

5 trong cơ sở dữ liệu:

Kotlin

@Dao interface UserDao {

@Update
fun updateUsers(vararg users: User)
}

Java

@Dao public interface UserDao {

@Update
public void updateUsers(User... users);
}

Room sử dụng để so khớp các phiên bản thực thể đã truyền với các hàng trong cơ sở dữ liệu. Nếu không có hàng nào có cùng một khoá chính, Room sẽ không thực hiện thay đổi.

Phương thức

@Dao interface UserDao {

@Update
fun updateUsers(vararg users: User)
}

9 có thể tuỳ ý trả về một giá trị

@Dao public interface UserDao {

@Update
public void updateUsers(User... users);
}

5 cho biết số lượng hàng đã được cập nhật thành công.

Xoá

Chú giải

@Dao public interface UserDao {

@Update
public void updateUsers(User... users);
}

6 cho phép bạn xác định các phương thức xoá những hàng cụ thể khỏi bảng cơ sở dữ liệu. Tương tự như phương thức

@Dao public interface UserDao {

@Insert(onConflict = OnConflictStrategy.REPLACE)
public void insertUsers(User... users);
@Insert
public void insertBothUsers(User user1, User user2);
@Insert
public void insertUsersAndFriends(User user, List friends);
}

6, phương thức

@Dao public interface UserDao {

@Update
public void updateUsers(User... users);
}

6 chấp nhận các phiên bản thực thể dữ liệu dưới dạng tham số. Đoạn mã sau đây cho thấy ví dụ về phương thức

@Dao public interface UserDao {

@Update
public void updateUsers(User... users);
}

6 cố gắng xoá một hoặc nhiều đối tượng

@Dao public interface UserDao {

@Insert(onConflict = OnConflictStrategy.REPLACE)
public void insertUsers(User... users);
@Insert
public void insertBothUsers(User user1, User user2);
@Insert
public void insertUsersAndFriends(User user, List friends);
}

5 khỏi cơ sở dữ liệu:

Kotlin

@Dao interface UserDao {

@Delete
fun deleteUsers(vararg users: User)
}

Java

@Dao public interface UserDao {

@Delete
public void deleteUsers(User... users);
}

Room sử dụng để so khớp các phiên bản thực thể đã truyền với các hàng trong cơ sở dữ liệu. Nếu không có hàng nào có cùng một khoá chính, Room sẽ không thực hiện thay đổi.

Phương thức

@Dao public interface UserDao {

@Update
public void updateUsers(User... users);
}

6 có thể tuỳ ý trả về một giá trị

@Dao public interface UserDao {

@Update
public void updateUsers(User... users);
}

5 cho biết số lượng hàng đã được xoá thành công.

Phương thức truy vấn

Chú giải

@Dao interface UserDao {

@Delete
fun deleteUsers(vararg users: User)
}

3 cho phép bạn ghi các câu lệnh SQL và hiển thị chúng dưới dạng các phương thức DAO. Hãy sử dụng các phương thức truy vấn này để truy vấn dữ liệu từ cơ sở dữ liệu của ứng dụng hoặc khi bạn cần thực hiện các thao tác chèn, cập nhật và xoá phức tạp hơn.

Room xác thực các truy vấn SQL vào thời gian biên dịch. Nói cách khác, nếu có vấn đề xảy ra với truy vấn của bạn, sẽ có lỗi biên dịch xảy ra thay vì lỗi thời gian chạy.

Truy vấn đơn giản

Mã sau đây xác định phương thức sử dụng một truy vấn

@Dao interface UserDao {

@Delete
fun deleteUsers(vararg users: User)
}

4 đơn giản để trả về tất cả các đối tượng

@Dao public interface UserDao {

@Insert(onConflict = OnConflictStrategy.REPLACE)
public void insertUsers(User... users);
@Insert
public void insertBothUsers(User user1, User user2);
@Insert
public void insertUsersAndFriends(User user, List friends);
}

5 trong cơ sở dữ liệu:

Kotlin

@Query("SELECT * FROM user") fun loadAllUsers(): Array

Java

@Query("SELECT * FROM user") public User[] loadAllUsers();

Các mục sau đây minh hoạ cách sửa đổi ví dụ này cho các trường hợp sử dụng thông thường.

Trả về một tập hợp nhỏ các cột của bảng

Trong hầu hết trường hợp, bạn chỉ cần trả về một tập hợp nhỏ các cột từ bảng mà bạn đang truy vấn. Ví dụ: Giao diện người dùng có thể chỉ hiển thị họ và tên của người dùng thay vì mọi thông tin chi tiết về người dùng đó. Để tiết kiệm tài nguyên và đơn giản hoá quá trình thực thi truy vấn, hãy chỉ truy vấn các trường mà bạn cần.

Room cho phép bạn trả về một đối tượng đơn giản từ bất kỳ truy vấn nào, miễn là bạn có thể liên kết tập hợp các cột kết quả đến đối tượng được trả về. Ví dụ: Bạn có thể xác định đối tượng sau để giữ họ và tên của người dùng:

Kotlin

@Dao public interface UserDao {

@Insert
void insertAll(User... users);
@Delete
void delete(User user);
@Query("SELECT * FROM user")
List getAll();
}

0

Java

@Dao public interface UserDao {

@Insert
void insertAll(User... users);
@Delete
void delete(User user);
@Query("SELECT * FROM user")
List getAll();
}

1

Sau đó, bạn có thể trả về đối tượng đơn giản đó từ phương thức truy vấn:

Kotlin

@Dao public interface UserDao {

@Insert
void insertAll(User... users);
@Delete
void delete(User user);
@Query("SELECT * FROM user")
List getAll();
}

2

Java

@Dao public interface UserDao {

@Insert
void insertAll(User... users);
@Delete
void delete(User user);
@Query("SELECT * FROM user")
List getAll();
}

3

Room hiểu rằng truy vấn trả về các giá trị cho cột

@Dao interface UserDao {

@Delete
fun deleteUsers(vararg users: User)
}

6 và

@Dao interface UserDao {

@Delete
fun deleteUsers(vararg users: User)
}

7. Các giá trị này có thể được liên kết đến các trường trong lớp

@Dao interface UserDao {

@Delete
fun deleteUsers(vararg users: User)
}

8. Nếu truy vấn trả về một cột không liên kết đến trường trong đối tượng được trả về, Room sẽ hiển thị cảnh báo.

Truyền các tham số đơn giản tới truy vấn

Trong hầu hết các trường hợp, các phương thức DAO của bạn cần chấp nhận các tham số để có thể thực hiện các thao tác lọc. Room hỗ trợ sử dụng các tham số phương thức làm tham số liên kết trong các truy vấn của bạn.

Ví dụ: Mã sau đây xác định một phương thức trả về tất cả người dùng trên một độ tuổi nhất định:

Kotlin

@Dao public interface UserDao {

@Insert
void insertAll(User... users);
@Delete
void delete(User user);
@Query("SELECT * FROM user")
List getAll();
}

4

Java

@Dao public interface UserDao {

@Insert
void insertAll(User... users);
@Delete
void delete(User user);
@Query("SELECT * FROM user")
List getAll();
}

5

Bạn cũng có thể truyền nhiều tham số hoặc tham chiếu cùng một tham số nhiều lần trong một truy vấn, như được minh hoạ trong mã sau:

Kotlin

@Dao public interface UserDao {

@Insert
void insertAll(User... users);
@Delete
void delete(User user);
@Query("SELECT * FROM user")
List getAll();
}

6

Java

@Dao public interface UserDao {

@Insert
void insertAll(User... users);
@Delete
void delete(User user);
@Query("SELECT * FROM user")
List getAll();
}

7

Truyền một tập hợp các tham số tới truy vấn

Một số phương thức DAO của bạn có thể yêu cầu bạn truyền số lượng tham số khác nhau chưa xác định cho đến thời gian chạy. Room hiểu khi một tham số đại diện cho một tập hợp và tự động mở rộng tập hợp đó trong thời gian chạy dựa trên số lượng tham số được cung cấp.

Ví dụ: Mã sau đây xác định một phương thức trả về thông tin liên quan đến tất cả người dùng từ một tập con các khu vực:

Kotlin

@Dao public interface UserDao {

@Insert
void insertAll(User... users);
@Delete
void delete(User user);
@Query("SELECT * FROM user")
List getAll();
}

8

Java

@Dao public interface UserDao {

@Insert
void insertAll(User... users);
@Delete
void delete(User user);
@Query("SELECT * FROM user")
List getAll();
}

9

Truy vấn nhiều bảng

Một số truy vấn của bạn có thể yêu cầu quyền truy cập vào nhiều bảng để tính toán kết quả. Bạn có thể sử dụng mệnh đề

@Dao interface UserDao {

@Delete
fun deleteUsers(vararg users: User)
}

9 trong các truy vấn SQL để tham chiếu nhiều bảng.

Mã sau đây xác định một phương thức kết hợp ba bảng với nhau để trả về kết quả các sách hiện đang cho một người dùng cụ thể mượn:

Kotlin

@Dao interface UserDao {

@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insertUsers(vararg users: User)
@Insert
fun insertBothUsers(user1: User, user2: User)
@Insert
fun insertUsersAndFriends(user: User, friends: List)
}

0

Java

@Dao interface UserDao {

@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insertUsers(vararg users: User)
@Insert
fun insertBothUsers(user1: User, user2: User)
@Insert
fun insertUsersAndFriends(user: User, friends: List)
}

1

Bạn cũng có thể xác định các đối tượng đơn giản để trả về một tập con các cột từ nhiều bảng đã kết hợp như được thảo luận trong phần . Mã sau đây xác định một DAO bằng phương thức trả về tên người dùng và tên sách mà họ đã mượn:

Kotlin

@Dao interface UserDao {

@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insertUsers(vararg users: User)
@Insert
fun insertBothUsers(user1: User, user2: User)
@Insert
fun insertUsersAndFriends(user: User, friends: List)
}

2

Java

@Dao interface UserDao {

@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insertUsers(vararg users: User)
@Insert
fun insertBothUsers(user1: User, user2: User)
@Insert
fun insertUsersAndFriends(user: User, friends: List)
}

3

Trả về kiểu cấu trúc đa ánh xạ (multimap)

Trong Room 2.4 trở lên, bạn cũng có thể truy vấn các cột từ nhiều bảng mà không cần xác định thêm lớp dữ liệu bằng cách ghi các phương thức truy vấn trả về đa ánh xạ.

Xem ví dụ trong phần . Thay vì trả về danh sách các phiên bản của một lớp dữ liệu tuỳ chỉnh chứa cặp phiên bản

@Dao public interface UserDao {

@Insert(onConflict = OnConflictStrategy.REPLACE)
public void insertUsers(User... users);
@Insert
public void insertBothUsers(User user1, User user2);
@Insert
public void insertUsersAndFriends(User user, List friends);
}

5 và

@Dao public interface UserDao {

@Delete
public void deleteUsers(User... users);
}

1, bạn có thể trực tiếp trả về một bản ánh xạ của

@Dao public interface UserDao {

@Insert(onConflict = OnConflictStrategy.REPLACE)
public void insertUsers(User... users);
@Insert
public void insertBothUsers(User user1, User user2);
@Insert
public void insertUsersAndFriends(User user, List friends);
}

5 và

@Dao public interface UserDao {

@Delete
public void deleteUsers(User... users);
}

1 từ phương thức truy vấn của mình:

Kotlin

@Dao interface UserDao {

@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insertUsers(vararg users: User)
@Insert
fun insertBothUsers(user1: User, user2: User)
@Insert
fun insertUsersAndFriends(user: User, friends: List)
}

4

Java

@Dao interface UserDao {

@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insertUsers(vararg users: User)
@Insert
fun insertBothUsers(user1: User, user2: User)
@Insert
fun insertUsersAndFriends(user: User, friends: List)
}

5

Khi phương thức truy vấn của bạn trả về đa ánh xạ, bạn có thể ghi các truy vấn sử dụng mệnh đề

@Dao public interface UserDao {

@Delete
public void deleteUsers(User... users);
}

4, cho phép bạn tận dụng các khả năng của SQL để tính toán và lọc nâng cao. Ví dụ: Bạn có thể sửa đổi phương thức

@Dao public interface UserDao {

@Delete
public void deleteUsers(User... users);
}

5 để chỉ trả về những người dùng đã mượn từ ba cuốn sách trở lên:

Kotlin

@Dao interface UserDao {

@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insertUsers(vararg users: User)
@Insert
fun insertBothUsers(user1: User, user2: User)
@Insert
fun insertUsersAndFriends(user: User, friends: List)
}

6

Java

@Dao interface UserDao {

@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insertUsers(vararg users: User)
@Insert
fun insertBothUsers(user1: User, user2: User)
@Insert
fun insertUsersAndFriends(user: User, friends: List)
}

7

Nếu không cần ánh xạ toàn bộ các đối tượng, bạn cũng có thể trả về các bản ánh xạ giữa các cột cụ thể trong truy vấn bằng cách đặt thuộc tính và trong chú giải

@Dao public interface UserDao {

@Delete
public void deleteUsers(User... users);
}

8 ở phương thức truy vấn của bạn:

Kotlin

@Dao interface UserDao {

@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insertUsers(vararg users: User)
@Insert
fun insertBothUsers(user1: User, user2: User)
@Insert
fun insertUsersAndFriends(user: User, friends: List)
}

8

Java

@Dao interface UserDao {

@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insertUsers(vararg users: User)
@Insert
fun insertBothUsers(user1: User, user2: User)
@Insert
fun insertUsersAndFriends(user: User, friends: List)
}

9

Loại dữ liệu trả về đặc biệt

Room cung cấp một số loại dữ liệu trả về đặc biệt để tích hợp với các thư viện API khác.

Truy vấn được phân trang bằng thư viện Paging

Room hỗ trợ các truy vấn phân trang thông qua việc tích hợp với thư viện Paging. Trong Room 2.3.0-alpha01 trở lên, DAO có thể trả về các đối tượng

@Dao public interface UserDao {

@Delete
public void deleteUsers(User... users);
}

9 để sử dụng cùng với Paging 3.

Kotlin

@Dao public interface UserDao {

@Insert(onConflict = OnConflictStrategy.REPLACE)
public void insertUsers(User... users);
@Insert
public void insertBothUsers(User user1, User user2);
@Insert
public void insertUsersAndFriends(User user, List friends);
}

0

Java

@Dao public interface UserDao {

@Insert(onConflict = OnConflictStrategy.REPLACE)
public void insertUsers(User... users);
@Insert
public void insertBothUsers(User user1, User user2);
@Insert
public void insertUsersAndFriends(User user, List friends);
}

1

Để biết thêm thông tin về cách chọn tham số loại cho

@Dao public interface UserDao {

@Delete
public void deleteUsers(User... users);
}

9, xin xem phần .

Quyền truy cập con trỏ trực tiếp

Nếu logic của ứng dụng yêu cầu quyền truy cập trực tiếp vào các hàng trả về, bạn có thể ghi các phương thức DAO để trả về đối tượng

@Query("SELECT * FROM user") fun loadAllUsers(): Array

1 như minh hoạ trong ví dụ sau đây: