با مجموعهها، منظم بمانید
ذخیره و طبقهبندی محتوا براساس اولویتهای شما.
از آنجایی که SQLite یک پایگاه داده رابطه ای است، می توانید روابط بین موجودیت ها را تعریف کنید. اما در حالی که اکثر کتابخانههای نگاشت شی-رابطهای به اشیاء موجودیت اجازه میدهند به یکدیگر ارجاع دهند، Room به صراحت این کار را ممنوع میکند. برای آشنایی با استدلال فنی پشت این تصمیم، به درک اینکه چرا اتاق به ارجاعات اشیا اجازه نمی دهد مراجعه کنید.
انواع روابط
اتاق از انواع روابط زیر پشتیبانی می کند:
یک به یک : رابطه ای را نشان می دهد که در آن یک موجودیت واحد با موجودیت واحد دیگری مرتبط است.
یک به چند : رابطه ای را نشان می دهد که در آن یک موجودیت واحد می تواند با چندین موجودیت از نوع دیگر مرتبط باشد.
Many-to-Many : نشان دهنده رابطه ای است که در آن چندین موجودیت از یک نوع می توانند به چندین موجودیت از نوع دیگر مرتبط شوند. این معمولا به یک میز اتصال نیاز دارد.
روابط تودرتو (با استفاده از اشیاء تعبیه شده) : رابطه ای را نشان می دهد که در آن موجودیت دارای موجودیت دیگری به عنوان یک فیلد است و این موجودیت تودرتو می تواند موجودیت های دیگری را نیز در بر گیرد. این از حاشیه نویسی @Embedded استفاده می کند.
بین دو رویکرد انتخاب کنید
در Room دو راه برای تعریف و پرس و جو رابطه بین موجودیت ها وجود دارد. می توانید از یکی از این دو استفاده کنید:
یک کلاس داده میانی با اشیاء تعبیه شده یا
یک روش پرس و جو رابطهای با نوع بازگشت چند نقشه.
اگر دلیل خاصی برای استفاده از کلاس های داده متوسط ندارید، توصیه می کنیم از رویکرد نوع بازگشت چند نقشه استفاده کنید. برای کسب اطلاعات بیشتر در مورد این رویکرد، به بازگشت یک نقشه چندگانه مراجعه کنید.
رویکرد کلاس داده متوسط به شما امکان می دهد از نوشتن پرس و جوهای پیچیده SQL اجتناب کنید، اما همچنین می تواند منجر به افزایش پیچیدگی کد شود زیرا به کلاس های داده اضافی نیاز دارد. به طور خلاصه، رویکرد نوع بازگشتی چند نقشه ای به درخواست های SQL شما برای انجام کارهای بیشتر نیاز دارد، و رویکرد کلاس داده متوسط به کد شما برای انجام کارهای بیشتر نیاز دارد.
از رویکرد کلاس داده متوسط استفاده کنید
در رویکرد کلاس داده میانی، شما یک کلاس داده تعریف می کنید که رابطه بین موجودیت های اتاق شما را مدل می کند. این کلاس داده جفتها را بین نمونههای یک موجودیت و نمونههای موجودیت دیگر بهعنوان اشیاء تعبیهشده نگه میدارد. سپس روشهای درخواست شما میتوانند نمونههایی از این کلاس داده را برای استفاده در برنامه شما برگردانند.
به عنوان مثال، می توانید یک کلاس داده UserBook را برای نمایش کاربران کتابخانه با کتاب های خاص بررسی شده تعریف کنید، و یک روش پرس و جو برای بازیابی لیستی از نمونه های UserBook از پایگاه داده تعریف کنید:
کاتلین
@DaointerfaceUserBookDao{@Query("SELECT user.name AS userName, book.name AS bookName "+"FROM user, book "+"WHERE user.id = book.user_id")funloadUserAndBookNames():LiveData<List<UserBook>>
}dataclassUserBook(valuserName:String?,valbookName:String?)
جاوا
@DaopublicinterfaceUserBookDao{@Query("SELECT user.name AS userName, book.name AS bookName "+"FROM user, book "+"WHERE user.id = book.user_id")publicLiveData<List<UserBook>>loadUserAndBookNames();}publicclassUserBook{publicStringuserName;publicStringbookName;}
از رویکرد انواع بازگشت چند نقشه استفاده کنید
در رویکرد نوع بازگشت چند نقشه، نیازی به تعریف هیچ کلاس داده اضافی ندارید. در عوض، شما یک نوع بازگشت چند نقشه را برای روش خود بر اساس ساختار نقشه ای که می خواهید تعریف می کنید و رابطه بین موجودیت های خود را مستقیماً در پرس و جوی SQL خود تعریف می کنید.
به عنوان مثال، روش پرس و جو زیر نقشهای از نمونههای User و Book برای نمایش کاربران کتابخانه با کتابهای خاص بررسی شده برمیگرداند:
کاتلین
@Query("SELECT * FROM user"+"JOIN book ON user.id = book.user_id")funloadUserAndBookNames():Map<User,List<Book>>
جاوا
@Query("SELECT * FROM user"+"JOIN book ON user.id = book.user_id")publicMap<User,List<Book>>loadUserAndBookNames();
ایجاد اشیاء تعبیه شده
گاهی اوقات، شما می خواهید یک موجودیت یا شی داده را به عنوان یک کل منسجم در منطق پایگاه داده خود بیان کنید، حتی اگر شی حاوی چندین فیلد باشد. در این مواقع، میتوانید از حاشیهنویسی @Embedded برای نشان دادن شیای که میخواهید به زیر فیلدهای آن در یک جدول تجزیه کنید، استفاده کنید. سپس میتوانید فیلدهای تعبیهشده را پرس و جو کنید، درست همانطور که برای ستونهای دیگر انجام میدهید.
به عنوان مثال، کلاس User شما میتواند شامل فیلدی از نوع Address باشد که ترکیبی از فیلدهایی به نامهای street ، city ، state و postCode را نشان میدهد. برای ذخیره ستون های تشکیل شده به طور جداگانه در جدول، یک فیلد Address قرار دهید. این باید در کلاس User با حاشیه نویسی @Embedded ظاهر شود. قطعه کد زیر این را نشان می دهد:
سپس جدولی که یک شی User را نشان میدهد شامل ستونهایی با نامهای زیر است: id ، firstName ، street ، state ، city و post_code .
اگر یک موجودیت دارای چندین فیلد جاسازی شده از یک نوع باشد، می توانید با تنظیم ویژگی prefix ، هر ستون را منحصر به فرد نگه دارید. سپس Room مقدار ارائه شده را به ابتدای نام هر ستون در شی جاسازی شده اضافه می کند.
منابع اضافی
برای کسب اطلاعات بیشتر در مورد تعریف روابط بین موجودات در اتاق، به منابع اضافی زیر مراجعه کنید.
محتوا و نمونه کدها در این صفحه مشمول پروانههای توصیفشده در پروانه محتوا هستند. جاوا و OpenJDK علامتهای تجاری یا علامتهای تجاری ثبتشده Oracle و/یا وابستههای آن هستند.
تاریخ آخرین بهروزرسانی 2024-11-30 بهوقت ساعت هماهنگ جهانی.
[[["درک آسان","easyToUnderstand","thumb-up"],["مشکلم را برطرف کرد","solvedMyProblem","thumb-up"],["غیره","otherUp","thumb-up"]],[["اطلاعاتی که نیاز دارم وجود ندارد","missingTheInformationINeed","thumb-down"],["بیشازحد پیچیده/ مراحل بسیار زیاد","tooComplicatedTooManySteps","thumb-down"],["قدیمی","outOfDate","thumb-down"],["مشکل ترجمه","translationIssue","thumb-down"],["مشکل کد / نمونهها","samplesCodeIssue","thumb-down"],["غیره","otherDown","thumb-down"]],["تاریخ آخرین بهروزرسانی 2024-11-30 بهوقت ساعت هماهنگ جهانی."],[],[],null,["# Choose relationship types between objects\n\nBecause SQLite is a relational database, you can define relationships between\nentities. But while most object-relational mapping libraries let entity objects\nreference each other, Room explicitly forbids this. To learn about the technical\nreasoning behind this decision, see [Understand why Room doesn't allow object\nreferences](/training/data-storage/room/referencing-data#understand-no-object-references).\n\nTypes of relationships\n----------------------\n\nRoom supports the following relationship types:\n\n- [**One-to-one**](/training/data-storage/room/relationships/one-to-one): Represents a relationship where a single entity is related to another single entity.\n- [**One-to-many**](/training/data-storage/room/relationships/one-to-many): Represents a relationship where a single entity can be related to multiple entities of another type.\n- [**Many-to-many**](/training/data-storage/room/relationships/many-to-many): Represents a relationship where multiple entities of one type can be related to multiple entities of another type. This usually requires a junction table.\n- [**Nested Relationships (using embedded objects)**](/training/data-storage/room/relationships/nested): Represents a relationship where an entity contains another entity as a field, and this nested entity can further contain other entities. This uses the `@Embedded` annotation.\n\nChoose between two approaches\n-----------------------------\n\nIn Room, there are two ways to define and query a relationship between entities.\nYou can use either:\n\n- An intermediate data class with embedded objects, or\n- A relational query method with a multimap return type.\n\nIf you don't have a specific reason to use intermediate data classes, we\nrecommend using the multimap return type approach. To learn more about this\napproach, see [Return a multimap](/training/data-storage/room/accessing-data#multimap).\n\nThe intermediate data class approach lets you avoid writing complex SQL queries,\nbut it can also result in increased code complexity because it requires\nadditional data classes. In short, the multimap return type approach requires\nyour SQL queries to do more work, and the intermediate data class approach\nrequires your code to do more work.\n\n### Use the intermediate data class approach\n\nIn the intermediate data class approach, you define a data class that models the\nrelationship between your Room entities. This data class holds the pairings\nbetween instances of one entity and instances of another entity as [embedded\nobjects](#nested-objects). Your query methods can then return instances of this data class for\nuse in your app.\n\nFor example, you can define a `UserBook` data class to represent library users\nwith specific books checked out, and define a query method to retrieve a list of\n`UserBook` instances from the database: \n\n### Kotlin\n\n @Dao\n interface UserBookDao {\n @Query(\n \"SELECT user.name AS userName, book.name AS bookName \" +\n \"FROM user, book \" +\n \"WHERE user.id = book.user_id\"\n )\n fun loadUserAndBookNames(): LiveData\u003cList\u003cUserBook\u003e\u003e\n }\n\n data class UserBook(val userName: String?, val bookName: String?)\n\n### Java\n\n @Dao\n public interface UserBookDao {\n @Query(\"SELECT user.name AS userName, book.name AS bookName \" +\n \"FROM user, book \" +\n \"WHERE user.id = book.user_id\")\n public LiveData\u003cList\u003cUserBook\u003e\u003e loadUserAndBookNames();\n }\n\n public class UserBook {\n public String userName;\n public String bookName;\n }\n\n### Use the multimap return types approach\n\n| **Note:** Room only supports multimap return types in version 2.4 and higher.\n\nIn the multimap return type approach, you don't need to define any additional\ndata classes. Instead, you define a [multimap](https://en.wikipedia.org/wiki/Multimap) return type for\nyour method based on the map structure that you want and define the relationship\nbetween your entities directly in your SQL query.\n\nFor example, the following query method returns a mapping of `User` and `Book`\ninstances to represent library users with specific books checked out: \n\n### Kotlin\n\n @Query(\n \"SELECT * FROM user\" +\n \"JOIN book ON user.id = book.user_id\"\n )\n fun loadUserAndBookNames(): Map\u003cUser, List\u003cBook\u003e\u003e\n\n### Java\n\n @Query(\n \"SELECT * FROM user\" +\n \"JOIN book ON user.id = book.user_id\"\n )\n public Map\u003cUser, List\u003cBook\u003e\u003e loadUserAndBookNames();\n\nCreate embedded objects\n-----------------------\n\nSometimes, you'd like to express an entity or data object as a cohesive whole in\nyour database logic, even if the object contains several fields. In these\nsituations, you can use the [`@Embedded`](/reference/androidx/room/Embedded) annotation to represent an object\nthat you'd like to decompose into its subfields within a table. You can then\nquery the embedded fields just as you do for other individual columns.\n\nFor example, your `User` class can include a field of type `Address` that\nrepresents a composition of fields named `street`, `city`, `state`, and\n`postCode`. To store the composed columns separately in the table, include an\n`Address` field. This should appear in the `User` class annotated with\n`@Embedded`. The following code snippet demonstrates this: \n\n### Kotlin\n\n data class Address(\n val street: String?,\n val state: String?,\n val city: String?,\n @ColumnInfo(name = \"post_code\") val postCode: Int\n )\n\n @Entity\n data class User(\n @PrimaryKey val id: Int,\n val firstName: String?,\n @Embedded val address: Address?\n )\n\n### Java\n\n public class Address {\n public String street;\n public String state;\n public String city;\n\n @ColumnInfo(name = \"post_code\") public int postCode;\n }\n\n @Entity\n public class User {\n @PrimaryKey public int id;\n\n public String firstName;\n\n @Embedded public Address address;\n }\n\nThe table representing a `User` object then contains columns with the following\nnames: `id`, `firstName`, `street`, `state`, `city`, and `post_code`.\n| **Note:** Embedded fields can also include other embedded fields.\n\nIf an entity has multiple embedded fields of the same type, you can keep each\ncolumn unique by setting the [`prefix`](/reference/androidx/room/Embedded#getPrefix()) property. Room then adds the\nprovided value to the beginning of each column name in the embedded object.\n\nAdditional resources\n--------------------\n\nTo learn more about defining relationships between entities in Room, see the\nfollowing additional resources.\n\n### Videos\n\n- [What's New in Room](https://www.youtube.com/watch?v=_aJsh6P00c0) (Android Dev Summit '19)\n\n### Blogs\n\n- [Database relations with Room](https://medium.com/androiddevelopers/database-relations-with-room-544ab95e4542)"]]