رابطه یک به چند بین دو موجودیت، رابطهای است که در آن هر نمونه از موجودیت والد با صفر یا چند نمونه از موجودیت فرزند مطابقت دارد، اما هر نمونه از موجودیت فرزند فقط میتواند دقیقاً با یک نمونه از موجودیت والد مطابقت داشته باشد.
در مثال برنامه پخش موسیقی، فرض کنید کاربر میتواند آهنگهای خود را در لیستهای پخش سازماندهی کند. هر کاربر میتواند به تعداد دلخواه لیست پخش ایجاد کند، اما دقیقاً یک کاربر هر لیست پخش را ایجاد میکند. بنابراین، یک رابطه یک به چند بین موجودیت User و موجودیت Playlist وجود دارد.
برای تعریف و پرس و جو از روابط یک به چند در پایگاه داده خود، این مراحل را دنبال کنید:
- تعریف رابطه : برای هر دو موجودیت کلاسهایی ایجاد کنید، به طوری که موجودیت فرزند به کلید اصلی والد ارجاع دهد.
- پرس و جو از موجودیتها : رابطه را در یک کلاس داده جدید مدلسازی کنید و تابعی را برای بازیابی دادههای مرتبط پیادهسازی کنید.
رابطه را تعریف کنید
برای تعریف یک رابطه یک به چند، ابتدا برای هر موجودیت یک کلاس ایجاد کنید. همانند رابطه یک به یک، موجودیت فرزند باید شامل یک متغیر باشد که به کلید اصلی موجودیت والد اشاره دارد.
@Entity data class User( @PrimaryKey val userId: Long, val name: String, val age: Int ) @Entity data class Playlist( @PrimaryKey val playlistId: Long, val userCreatorId: Long, val playlistName: String )
پرس و جو از موجودیتها
برای پرس و جو از لیست کاربران و لیستهای پخش مربوطه، ابتدا باید رابطه یک به چند بین این دو موجودیت را مدلسازی کنید.
برای مدلسازی رابطه، یک کلاس داده جدید ایجاد کنید. هر نمونه از این کلاس، یک نمونه از موجودیت والد و لیستی از تمام نمونههای موجودیت فرزند مربوطه را در خود جای میدهد. حاشیهنویسی @Relation را به خاصیتی که لیست موجودیتهای فرزند را نشان میدهد، اضافه کنید. parentColumns را برابر با نام ستون کلید اصلی موجودیت والد و entityColumns را برابر با نام ستون موجودیت فرزندی که به کلید اصلی موجودیت والد اشاره میکند، تنظیم کنید.
data class UserWithPlaylists( @Embedded val user: User, @Relation( parentColumns = ["userId"], entityColumns = ["userCreatorId"] ) val playlists: List<Playlist> )
در نهایت، یک تابع به کلاس شیء دسترسی به داده (DAO) اضافه کنید که تمام نمونههای کلاس دادهای که موجودیت والد و موجودیت فرزند را جفت میکند، برمیگرداند. حاشیهنویسی @Transaction را اضافه کنید تا Room کل عملیات را به صورت اتمی انجام دهد. این حاشیهنویسی ضروری است زیرا این تابع به Room نیاز دارد تا دو پرسوجو اجرا کند.
@Transaction @Query("SELECT * FROM User") suspend fun getUsersWithPlaylists(): List<UserWithPlaylists>
کلیدهای ترکیبی
اگر رابطه را با استفاده از کلیدهای مرکب تعریف میکنید، چندین ستون را در parentColumns و entityColumns مشخص کنید. ترتیب ستونها در parentColumns باید با ترتیب ستونها در entityColumns مطابقت داشته باشد.
@Entity(primaryKeys = ["firstName", "lastName"]) data class User( val firstName: String, val lastName: String, val age: Int ) @Entity data class Playlist( @PrimaryKey val playlistId: Long, val userFirstName: String, val userLastName: String, val playlistName: String ) data class UserWithPlaylists( @Embedded val user: User, @Relation( parentColumns = ["firstName", "lastName"], entityColumns = ["userFirstName", "userLastName"] ) val playlists: List<Playlist> )