เมื่อคุณใช้ไลบรารีความต่อเนื่องของห้องแชทเพื่อจัดเก็บข้อมูลของแอป คุณจะโต้ตอบ กับข้อมูลที่จัดเก็บไว้โดยการกำหนดออบเจ็กต์การเข้าถึงข้อมูล หรือ DAO แต่ละ DAO รวมวิธีการที่ให้การเข้าถึงฐานข้อมูลของแอปแบบนามธรรม ขณะคอมไพล์ Room จะสร้างการใช้งาน DAO ที่คุณกำหนดโดยอัตโนมัติ
ใช้ DAO เพื่อเข้าถึงฐานข้อมูลของแอปแทนเครื่องมือสร้างคำค้นหาหรือโดยตรง คุณสามารถเก็บการแยก ความกังวลทางสถาปัตยกรรมที่สำคัญ หลัก นอกจากนี้ DAO ยังช่วยให้คุณจำลองการเข้าถึงฐานข้อมูลได้ง่ายขึ้น ทดสอบแอปของคุณ
การวิเคราะห์ DAO
คุณสามารถกำหนด DAO แต่ละรายการเป็นอินเทอร์เฟซหรือคลาสนามธรรมก็ได้ สำหรับขั้นพื้นฐาน
กรณีการใช้งาน คุณมักจะใช้อินเทอร์เฟซ ไม่ว่าจะเป็นกรณีใด คุณต้อง
เพิ่มคำอธิบายประกอบ DAO ของคุณด้วย @Dao
DAO
ไม่มีพร็อพเพอร์ตี้ แต่ได้กำหนดวิธีการโต้ตอบอย่างน้อย 1 วิธี
กับข้อมูลในฐานข้อมูลของแอป
โค้ดต่อไปนี้เป็นตัวอย่างของ DAO แบบง่ายที่กำหนดเมธอดสำหรับ
การแทรก การลบ และเลือกออบเจ็กต์ User
รายการในฐานข้อมูลห้อง
Kotlin
@Dao interface UserDao { @Insert fun insertAll(vararg users: User) @Delete fun delete(user: User) @Query("SELECT * FROM user") fun getAll(): List<User> }
Java
@Dao public interface UserDao { @Insert void insertAll(User... users); @Delete void delete(User user); @Query("SELECT * FROM user") List<User> getAll(); }
มีเมธอด DAO ที่กำหนดการโต้ตอบของฐานข้อมูลอยู่ 2 ประเภท ได้แก่
- วิธีการที่สะดวกที่ช่วยให้คุณแทรก อัปเดต และลบแถวใน ฐานข้อมูลโดยไม่ต้องเขียนรหัส SQL
- เมธอดการค้นหาที่ช่วยให้คุณเขียนการค้นหา SQL ของคุณเองเพื่อโต้ตอบกับ ฐานข้อมูล
ส่วนต่อไปนี้จะแสดงวิธีใช้เมธอด DAO ทั้ง 2 ประเภทเพื่อวัตถุประสงค์ต่อไปนี้ กำหนดการโต้ตอบของฐานข้อมูลที่แอปของคุณต้องใช้
วิธีการตามสะดวก
ห้องพักมีคำอธิบายประกอบอำนวยความสะดวกสำหรับระบุวิธีการที่เรียบง่าย การแทรก อัปเดต และการลบโดยที่คุณไม่ต้องเขียนคำสั่ง SQL
ถ้าคุณต้องการระบุส่วนแทรก อัปเดต หรือการลบที่ซับซ้อนขึ้น หรือถ้าต้องการ เพื่อค้นหาข้อมูลในฐานข้อมูล ให้ใช้เมธอดการค้นหาแทน
แทรก
คำอธิบายประกอบ @Insert
ช่วยให้คุณ
กำหนดวิธีการที่แทรกพารามิเตอร์ลงในตารางที่เหมาะสมใน
ฐานข้อมูล โค้ดต่อไปนี้แสดงตัวอย่างเมธอด @Insert
ที่ถูกต้องซึ่ง
แทรกออบเจ็กต์ User
อย่างน้อย 1 รายการในฐานข้อมูล
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<User>) }
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<User> friends); }
พารามิเตอร์แต่ละรายการสำหรับเมธอด @Insert
ต้องเป็นอินสแตนซ์ของห้องแชท
คลาสเอนทิตีข้อมูลมีคำอธิบายประกอบด้วย
@Entity
หรือคอลเล็กชันของอินสแตนซ์คลาสเอนทิตีข้อมูล โดยที่แต่ละรายการ
ชี้ไปยังฐานข้อมูล เมื่อมีการเรียกเมธอด @Insert
ห้องแชทจะแทรกแต่ละเมธอด
ส่งอินสแตนซ์ของเอนทิตีไปยังตารางฐานข้อมูลที่เกี่ยวข้อง
หากเมธอด @Insert
ได้รับพารามิเตอร์เดียว ก็จะแสดง long
ได้
ซึ่งเป็น rowId
ใหม่สำหรับรายการที่แทรก หากพารามิเตอร์เป็น
อาร์เรย์หรือคอลเล็กชัน แล้วแสดงผลอาร์เรย์หรือคอลเล็กชัน
แทน long
ค่า โดยแต่ละค่าเป็น rowId
สำหรับหนึ่งในรายการที่แทรก
รายการ ดูข้อมูลเพิ่มเติมเกี่ยวกับการแสดงผลค่า rowId
ได้ในข้อมูลอ้างอิง
เอกสารประกอบสำหรับ @Insert
คำอธิบายประกอบ และเอกสาร SQLite สำหรับ Rowid
ตาราง
อัปเดต
คำอธิบายประกอบ @Update
ช่วยให้คุณ
กำหนดวิธีการที่อัปเดตแถวที่ระบุในตารางฐานข้อมูล ชอบ
เมธอด @Insert
, เมธอด @Update
จะยอมรับอินสแตนซ์เอนทิตีข้อมูลเป็นพารามิเตอร์
โค้ดต่อไปนี้แสดงตัวอย่างของเมธอด @Update
ที่พยายามจะ
อัปเดตออบเจ็กต์ User
อย่างน้อย 1 รายการในฐานข้อมูล:
Kotlin
@Dao interface UserDao { @Update fun updateUsers(vararg users: User) }
Java
@Dao public interface UserDao { @Update public void updateUsers(User... users); }
ห้องแชทใช้พารามิเตอร์ คีย์เพื่อจับคู่คำที่ผ่านแล้ว อินสแตนซ์ของเอนทิตีไปยังแถวในฐานข้อมูล หากไม่มีแถวที่มี คีย์หลัก ห้องแชทไม่มีการเปลี่ยนแปลงใดๆ
เมธอด @Update
อาจแสดงผลค่า int
ที่ระบุตัวเลขหรือไม่ก็ได้
ของแถวที่อัปเดตสำเร็จ
ลบ
คำอธิบายประกอบ @Delete
ช่วยให้คุณ
กำหนด Method เพื่อลบแถวที่ระบุจากตารางฐานข้อมูล ชอบ
เมธอด @Insert
, เมธอด @Delete
จะยอมรับอินสแตนซ์เอนทิตีข้อมูลเป็นพารามิเตอร์
โค้ดต่อไปนี้แสดงตัวอย่างของเมธอด @Delete
ที่พยายามจะ
ลบออบเจ็กต์ User
อย่างน้อย 1 รายการออกจากฐานข้อมูล:
Kotlin
@Dao interface UserDao { @Delete fun deleteUsers(vararg users: User) }
Java
@Dao public interface UserDao { @Delete public void deleteUsers(User... users); }
ห้องแชทใช้พารามิเตอร์ คีย์เพื่อจับคู่คำที่ผ่านแล้ว อินสแตนซ์ของเอนทิตีไปยังแถวในฐานข้อมูล หากไม่มีแถวที่มี คีย์หลัก ห้องแชทไม่มีการเปลี่ยนแปลงใดๆ
เมธอด @Delete
อาจแสดงผลค่า int
ที่ระบุจำนวนของ
แถวที่ถูกลบสำเร็จ
วิธีการค้นหา
คำอธิบายประกอบ @Query
ช่วยให้คุณ
เขียนคำสั่ง SQL และแสดงเป็นเมธอด DAO ใช้วิธีการค้นหาเหล่านี้เพื่อ
ค้นหาข้อมูลจากฐานข้อมูลของแอปหรือเมื่อต้องการดำเนินการที่ซับซ้อนมากขึ้น
การแทรก อัปเดต และการลบ
Room จะตรวจสอบการค้นหา SQL ในเวลาคอมไพล์ ซึ่งหมายความว่าหากมีปัญหา พร้อมกับการค้นหา ข้อผิดพลาดของการคอมไพล์จะเกิดขึ้นแทนที่รันไทม์ล้มเหลว
คำค้นหาแบบง่าย
โค้ดต่อไปนี้ระบุเมธอดที่ใช้คำค้นหา SELECT
แบบง่ายเพื่อแสดงผล
ออบเจ็กต์ User
ทั้งหมดในฐานข้อมูล:
Kotlin
@Query("SELECT * FROM user") fun loadAllUsers(): Array<User>
Java
@Query("SELECT * FROM user") public User[] loadAllUsers();
ส่วนต่อไปนี้จะแสดงวิธีแก้ไขตัวอย่างนี้สำหรับการใช้งานโดยทั่วไป กรณี
แสดงผลชุดย่อยของคอลัมน์ในตาราง
ส่วนใหญ่แล้ว คุณจะแสดงเพียงชุดย่อยของคอลัมน์จากตาราง ที่คุณกำลังสอบถาม ตัวอย่างเช่น UI อาจแสดงแค่ นามสกุลของผู้ใช้ ไม่ใช่รายละเอียดทั้งหมดเกี่ยวกับผู้ใช้รายนั้น เพื่อบันทึก ทรัพยากรและลดความซับซ้อนของการดำเนินการค้นหา ให้ค้นหาเฉพาะ ฟิลด์ที่คุณต้องการ
Room ช่วยให้คุณส่งคืนออบเจ็กต์ง่ายๆ จากคำค้นหาใดก็ได้ คุณสามารถจับคู่ชุดคอลัมน์ผลลัพธ์กับออบเจ็กต์ที่แสดงผล ตัวอย่างเช่น คุณสามารถ สามารถกำหนดออบเจ็กต์ต่อไปนี้เพื่อเก็บชื่อและนามสกุลของผู้ใช้
Kotlin
data class NameTuple( @ColumnInfo(name = "first_name") val firstName: String?, @ColumnInfo(name = "last_name") val lastName: String? )
Java
public class NameTuple { @ColumnInfo(name = "first_name") public String firstName; @ColumnInfo(name = "last_name") @NonNull public String lastName; }
จากนั้นคุณจะส่งคืนออบเจ็กต์ง่ายๆ นั้นจากวิธีการค้นหาได้ โดยทำดังนี้
Kotlin
@Query("SELECT first_name, last_name FROM user") fun loadFullName(): List<NameTuple>
Java
@Query("SELECT first_name, last_name FROM user") public List<NameTuple> loadFullName();
ห้องแชทเข้าใจว่าการค้นหาแสดงผลค่าสำหรับ first_name
และ
last_name
คอลัมน์ และสามารถนำค่าเหล่านี้มาแมปกับช่องใน
NameTuple
ชั้นเรียน หากข้อความค้นหาแสดงคอลัมน์ที่ไม่ได้จับคู่กับฟิลด์
ในวัตถุที่ส่งคืน ห้องจะแสดงคำเตือน
ส่งต่อพารามิเตอร์พื้นฐานไปยังการค้นหา
ส่วนใหญ่แล้ว เมธอด DAO จะต้องยอมรับพารามิเตอร์เพื่อให้สามารถ ดำเนินการกรอง ห้องแชทรองรับการใช้พารามิเตอร์เมธอดเป็นการเชื่อมโยง ในข้อความค้นหาของคุณ
ตัวอย่างเช่น โค้ดต่อไปนี้กำหนดเมธอดที่จะแสดงผลผู้ใช้ทั้งหมด ที่มีอายุมากกว่าเกณฑ์ที่กำหนด:
Kotlin
@Query("SELECT * FROM user WHERE age > :minAge") fun loadAllUsersOlderThan(minAge: Int): Array<User>
Java
@Query("SELECT * FROM user WHERE age > :minAge") public User[] loadAllUsersOlderThan(int minAge);
คุณยังส่งผ่านพารามิเตอร์หลายรายการหรืออ้างอิงพารามิเตอร์เดียวกันหลายรายการได้ด้วย จำนวนครั้งในข้อความค้นหา ดังที่แสดงในโค้ดต่อไปนี้:
Kotlin
@Query("SELECT * FROM user WHERE age BETWEEN :minAge AND :maxAge") fun loadAllUsersBetweenAges(minAge: Int, maxAge: Int): Array<User> @Query("SELECT * FROM user WHERE first_name LIKE :search " + "OR last_name LIKE :search") fun findUserWithName(search: String): List<User>
Java
@Query("SELECT * FROM user WHERE age BETWEEN :minAge AND :maxAge") public User[] loadAllUsersBetweenAges(int minAge, int maxAge); @Query("SELECT * FROM user WHERE first_name LIKE :search " + "OR last_name LIKE :search") public List<User> findUserWithName(String search);
ส่งคอลเล็กชันของพารามิเตอร์ไปยังการค้นหา
บางเมธอด DAO ของคุณอาจกำหนดให้คุณต้องส่งผ่านจำนวนตัวแปร พารามิเตอร์ที่ไม่รู้จักจนถึงรันไทม์ ห้องแชทจะเข้าใจเมื่อพารามิเตอร์ แสดงคอลเล็กชันและขยายโดยอัตโนมัติที่รันไทม์ตาม จำนวนพารามิเตอร์ที่ระบุ
ตัวอย่างเช่น โค้ดต่อไปนี้จะระบุเมธอดที่แสดงข้อมูลเกี่ยวกับ ผู้ใช้ทั้งหมดจากภูมิภาคย่อยๆ ดังนี้
Kotlin
@Query("SELECT * FROM user WHERE region IN (:regions)") fun loadUsersFromRegions(regions: List<String>): List<User>
Java
@Query("SELECT * FROM user WHERE region IN (:regions)") public List<User> loadUsersFromRegions(List<String> regions);
สืบค้นตารางข้อมูลหลายรายการ
การค้นหาบางรายการอาจต้องเข้าถึงหลายตารางเพื่อคำนวณ
ผลลัพธ์ คุณสามารถใช้วลี JOIN
ในการค้นหา SQL เพื่ออ้างอิงอักขระมากกว่า
1 ตาราง
โค้ดต่อไปนี้จะกำหนดเมธอดที่รวม 3 ตารางเข้าด้วยกันเพื่อแสดงผล หนังสือที่ยืมไว้ให้ผู้ใช้รายหนึ่งในปัจจุบัน:
Kotlin
@Query( "SELECT * FROM book " + "INNER JOIN loan ON loan.book_id = book.id " + "INNER JOIN user ON user.id = loan.user_id " + "WHERE user.name LIKE :userName" ) fun findBooksBorrowedByNameSync(userName: String): List<Book>
Java
@Query("SELECT * FROM book " + "INNER JOIN loan ON loan.book_id = book.id " + "INNER JOIN user ON user.id = loan.user_id " + "WHERE user.name LIKE :userName") public List<Book> findBooksBorrowedByNameSync(String userName);
นอกจากนี้คุณยังกำหนดออบเจ็กต์ง่ายๆ เพื่อแสดงชุดย่อยของคอลัมน์จากหลายรายการได้ ตารางที่เข้าร่วม ตามที่อธิบายไว้ใน ส่งคืนข้อมูลบางส่วนของตาราง คอลัมน์ โค้ดต่อไปนี้กำหนด DAO ด้วยเมธอดที่ แสดงชื่อผู้ใช้และชื่อหนังสือที่ยืม:
Kotlin
interface UserBookDao { @Query( "SELECT user.name AS userName, book.name AS bookName " + "FROM user, book " + "WHERE user.id = book.user_id" ) fun loadUserAndBookNames(): LiveData<List<UserBook>> // You can also define this class in a separate file. data class UserBook(val userName: String?, val bookName: String?) }
Java
@Dao public interface UserBookDao { @Query("SELECT user.name AS userName, book.name AS bookName " + "FROM user, book " + "WHERE user.id = book.user_id") public LiveData<List<UserBook>> loadUserAndBookNames(); // You can also define this class in a separate file, as long as you add the // "public" access modifier. static class UserBook { public String userName; public String bookName; } }
แสดงผลมัลติแมป
ในห้อง 2.4 ขึ้นไป คุณสามารถค้นหาคอลัมน์จากหลายตารางได้โดยไม่ต้อง การกำหนดคลาสข้อมูลเพิ่มเติมโดยการเขียนวิธีการค้นหาที่ส่งคืน multimap
ลองดูตัวอย่างจากส่วนสืบค้นข้อมูลหลายตาราง
แทนที่จะส่งคืนรายการของอินสแตนซ์ของคลาสข้อมูลที่กำหนดเองที่เก็บไว้
การจับคู่อินสแตนซ์ User
และ Book
คุณจะแสดงผลการแมปของ User
และ
Book
โดยตรงจากวิธีข้อความค้นหาของคุณ:
Kotlin
@Query( "SELECT * FROM user" + "JOIN book ON user.id = book.user_id" ) fun loadUserAndBookNames(): Map<User, List<Book>>
Java
@Query( "SELECT * FROM user" + "JOIN book ON user.id = book.user_id" ) public Map<User, List<Book>> loadUserAndBookNames();
เมื่อวิธีการค้นหาแสดงผลมัลติแมป คุณสามารถเขียนคำค้นหาที่ใช้
GROUP BY
วลี ซึ่งช่วยให้คุณใช้ประโยชน์จากความสามารถของ SQL สำหรับ
การคำนวณและการกรองขั้นสูง เช่น คุณสามารถแก้ไข
เมธอด loadUserAndBookNames()
เพื่อแสดงผลผู้ใช้ที่มีหนังสือ 3 เล่มขึ้นไปเท่านั้น
เช็คเอาต์:
Kotlin
@Query( "SELECT * FROM user" + "JOIN book ON user.id = book.user_id" + "GROUP BY user.name WHERE COUNT(book.id) >= 3" ) fun loadUserAndBookNames(): Map<User, List<Book>>
Java
@Query( "SELECT * FROM user" + "JOIN book ON user.id = book.user_id" + "GROUP BY user.name WHERE COUNT(book.id) >= 3" ) public Map<User, List<Book>> loadUserAndBookNames();
หากไม่ต้องการแมปวัตถุทั้งหมด คุณแสดงการจับคู่ระหว่าง
คอลัมน์ที่เฉพาะเจาะจงใน Query ของคุณโดยการตั้งค่า
keyColumn
และ
แอตทริบิวต์ของ valueColumn
ในคำอธิบายประกอบ @MapInfo
ใน
วิธีการค้นหา:
Kotlin
@MapInfo(keyColumn = "userName", valueColumn = "bookName") @Query( "SELECT user.name AS username, book.name AS bookname FROM user" + "JOIN book ON user.id = book.user_id" ) fun loadUserAndBookNames(): Map<String, List<String>>
Java
@MapInfo(keyColumn = "userName", valueColumn = "bookName") @Query( "SELECT user.name AS username, book.name AS bookname FROM user" + "JOIN book ON user.id = book.user_id" ) public Map<String, List<String>> loadUserAndBookNames();
ประเภทการแสดงผลพิเศษ
ห้องพักมีประเภทผลลัพธ์พิเศษสำหรับการผสานรวมกับ API อื่นๆ ห้องสมุด
การค้นหาที่ใส่เลขหน้าด้วยไลบรารีการสร้างหน้า
Room รองรับการค้นหาที่ใส่เลขหน้าผ่านการผสานรวมกับ การแบ่งหน้า
คลัง ในห้อง 2.3.0-alpha01 และ
ที่สูงขึ้น DAO สามารถแสดงผล
PagingSource
ออบเจ็กต์สำหรับการใช้งาน
กับหน้า 3
Kotlin
@Dao interface UserDao { @Query("SELECT * FROM users WHERE label LIKE :query") fun pagingSource(query: String): PagingSource<Int, User> }
Java
@Dao interface UserDao { @Query("SELECT * FROM users WHERE label LIKE :query") PagingSource<Integer, User> pagingSource(String query); }
สำหรับข้อมูลเพิ่มเติมเกี่ยวกับการเลือกพารามิเตอร์ประเภทสำหรับ PagingSource
โปรดดู
เลือกคีย์และค่า
ประเภทต่างๆ
การเข้าถึงเคอร์เซอร์โดยตรง
คุณสามารถเขียนหากตรรกะของแอปต้องการสิทธิ์เข้าถึงแถวผลลัพธ์โดยตรง
เมธอด DAO ของคุณเพื่อแสดงผล Cursor
ตามที่แสดงในตัวอย่างต่อไปนี้
Kotlin
@Dao interface UserDao { @Query("SELECT * FROM user WHERE age > :minAge LIMIT 5") fun loadRawUsersOlderThan(minAge: Int): Cursor }
Java
@Dao public interface UserDao { @Query("SELECT * FROM user WHERE age > :minAge LIMIT 5") public Cursor loadRawUsersOlderThan(int minAge); }
แหล่งข้อมูลเพิ่มเติม
ดูข้อมูลเพิ่มเติมเกี่ยวกับการเข้าถึงข้อมูลโดยใช้ DAO ของห้องได้จากหัวข้อเพิ่มเติมต่อไปนี้ แหล่งข้อมูล: