عند استخدام مكتبة الاحتفاظ بالبيانات في الغرفة لتخزين بيانات تطبيقك، بالبيانات المخزنة من خلال تحديد كائنات الوصول إلى البيانات، أو DAO. كل مقياس DAO على طرق توفر وصولاً مجردًا إلى قاعدة بيانات التطبيق. التجميع ينشئ الغرفة تلقائيًا عمليات تنفيذ DAO التي تحددها.
من خلال استخدام DAO للوصول إلى قاعدة بيانات التطبيق بدلاً من أدوات إنشاء الطلبات أو توجيه فيمكنك الحفاظ على فصل المخاوف ذات الصلة، وهو هندسة معمارية مهمة المبدأ. تسهّل عليك أنظمة DAO أيضًا محاكاة الوصول إلى قاعدة البيانات عندما اختبار تطبيقك
تحليل جهاز DAO
يمكنك تعريف كل DAO إما كواجهة أو فئة مجردة. للإصدارات الأساسية:
حالات الاستخدام، فعادةً ما تستخدم واجهة. في كلتا الحالتين، يجب عليك دائمًا
أضِف تعليقات توضيحية إلى رموز DAO الخاصة بك باستخدام @Dao
. أجهزة DAO
لا تمتلك خصائص، لكنها تحدد طريقة واحدة أو أكثر للتفاعل
مع البيانات في قاعدة بيانات التطبيق.
التعليمة البرمجية التالية هي مثال على 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 التي تحدد تفاعلات قاعدة البيانات:
- طريقة ملائمة تتيح لك إدراج الصفوف وتعديلها وحذفها في قاعدة البيانات دون كتابة أي تعليمة برمجية لـ SQL.
- طرق الاستعلام التي تتيح لك كتابة استعلام SQL الخاص بك للتفاعل مع قاعدة البيانات.
توضح الأقسام التالية كيفية استخدام كلا النوعين من طرق DAO وتحدد تفاعلات قاعدة البيانات التي يحتاجها تطبيقك.
الطرق الملائمة
توفر الغرفة تعليقات توضيحية للملاءمة لتحديد الطرق التي تعمل الإدراجات والتحديثات وعمليات الحذف دون الحاجة إلى كتابة عبارة SQL.
إذا كنت بحاجة إلى تعريف عمليات إدراج أو تعديلات أو عمليات حذف أكثر تعقيدًا، أو إذا كنت بحاجة إلى لطلب البحث عن بيانات في قاعدة البيانات، استخدِم طريقة طلب البحث بدلاً من ذلك.
إدراج
يتيح لك التعليق التوضيحي @Insert
تحديد الطرق التي تُدرج معاملاتها في الجدول المناسب
قاعدة البيانات. يعرض الرمز التالي أمثلة على طرق @Insert
الصالحة التي
إدراج كائن User
واحد أو أكثر في قاعدة البيانات:
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 لمعرّف الصف
الجداول.
تعديل
يتيح لك التعليق التوضيحي @Update
تحديد الطرق التي تعمل على تحديث صفوف معينة في جدول قاعدة بيانات. أعجبني
@Insert
طريقة، تقبل طريقة واحدة (@Update
) حالات كيان البيانات كمَعلمات.
يوضح الرمز التالي مثالاً على طريقة @Update
تحاول
تعديل عنصر User
واحد أو أكثر في قاعدة البيانات:
Kotlin
@Dao interface UserDao { @Update fun updateUsers(vararg users: User) }
Java
@Dao public interface UserDao { @Update public void updateUsers(User... users); }
تستخدم الغرفة المفتاح لمطابقة تم اجتيازه مثيلات الكيان إلى صفوف في قاعدة البيانات. إذا لم يكن هناك صف بنفس المفتاح الأساسي، لا تجري الغرفة أي تغييرات.
يمكن لطريقة @Update
أن تعرض بشكل اختياري قيمة int
تشير إلى الرقم.
من الصفوف التي تم تحديثها بنجاح.
حذف
يتيح لك التعليق التوضيحي @Delete
تحديد الطرق التي تحذف صفوفًا معينة من جدول قاعدة بيانات. أعجبني
@Insert
طريقة، تقبل طريقة واحدة (@Delete
) حالات كيان البيانات كمَعلمات.
يوضح الرمز التالي مثالاً على طريقة @Delete
تحاول
حذف عنصر User
واحد أو أكثر من قاعدة البيانات:
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. استخدم طرق الاستعلام هذه
الاستعلام عن البيانات من قاعدة بيانات التطبيق أو عندما تحتاج إلى تنفيذ إجراءات أكثر تعقيدًا
الإدخالات والتحديثات وعمليات الحذف.
تتحقّق الغرفة من صحة استعلامات SQL في وقت التجميع. هذا يعني أنه إذا كانت هناك مشكلة مع طلب البحث، يحدث خطأ في التحويل البرمجي بدلاً من إخفاق بيئة التشغيل.
طلبات بحث بسيطة
يحدد الرمز التالي طريقة تستخدم استعلام SELECT
بسيط لعرض
كافة كائنات User
في قاعدة البيانات:
Kotlin
@Query("SELECT * FROM user") fun loadAllUsers(): Array<User>
Java
@Query("SELECT * FROM user") public User[] loadAllUsers();
توضح الأقسام التالية كيفية تعديل هذا المثال للاستخدام النموذجي. الحالات.
إرجاع مجموعة فرعية من أعمدة الجدول
في معظم الأحيان، تحتاج فقط إلى عرض مجموعة فرعية من الأعمدة من الجدول التي تستعلم عنها. على سبيل المثال، قد تعرض واجهة المستخدم الصفحة الأولى فقط اسم العائلة للمستخدم بدلاً من كل التفاصيل المتعلقة بهذا المستخدم. للحفظ الموارد وتبسيط تنفيذ طلب البحث، فما عليك سوى الاستعلام عن الحقول التي تحتاجها.
تتيح لك الغرفة عرض كائن بسيط من أي من طلبات البحث الخاصة بك طالما يمكنك تعيين مجموعة أعمدة النتائج على الكائن الذي تم إرجاعه. على سبيل المثال، يمكن تحديد الكائن التالي لحمل الاسم الأول واسم العائلة للمستخدم:
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 للإشارة إلى أكثر من
جدول واحد.
تحدد التعليمة البرمجية التالية طريقة تربط ثلاثة جداول معًا لإرجاعها الكتب التي تتم إعارتها حاليًا إلى مستخدم محدَّد:
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 والإصدارات الأحدث، يمكنك أيضًا الاستعلام عن الأعمدة من جداول متعددة بدون فئة بيانات إضافية عن طريق كتابة طرق الاستعلام التي تُرجع خريطة متعددة.
يمكنك الاطّلاع على المثال من قسم طلب البحث في جداول متعددة.
بدلاً من عرض قائمة بمثيلات فئة بيانات مخصّصة تحتفظ
إقران مثيلات الـ 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()
لعرض المستخدمين الذين لديهم ثلاثة كتب أو أكثر فقط
تسجيل المغادرة:
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();
إذا كنت لا تحتاج إلى ربط عناصر بأكملها، يمكنك أيضًا إرجاع التعيينات بين
أعمدة محددة في استعلامك عن طريق تعيين
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();
أنواع إرجاع خاصة
توفّر الغرفة بعض أنواع الإرجاع الخاصة لدمجها مع واجهة برمجة التطبيقات الأخرى. المكتبات.
طلبات البحث المقسّمة على صفحات باستخدام مكتبة الصفحات
تتوافق الغرفة مع طلبات البحث المقسّمة إلى صفحات من خلال الدمج مع ميزة التقسيم إلى صفحات.
المكتبة. في الغرفة 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 الخاصة بالغرفة، يُرجى الاطّلاع على المعلومات الإضافية التالية الموارد: