SQLite ilişkisel bir veritabanı olduğundan, Google Analytics 4'teki varlıklarından oluşur. Ancak çoğu nesne ilişkisel eşleme kitaplığı, nesneler birbirine referansta bulunuyorsa Oda, bunu açıkça yasaklar. Hakkında bilgi edinmek için daha fazla bilgi için Odanın, neden karar vermediğini nesne başvurularına izin verme başlıklı makaleye bakın.
İki olası yaklaşım
Oda'da, varlıklar arasındaki bir ilişkiyi tanımlamanın ve sorgulamanın iki yolu vardır: veya mevcut bir yerleştirilmiş nesneler veya çoklu harita döndürmeli ilişkisel sorgu yöntemi türü.
Orta veri sınıfı
Orta düzey veri sınıfı yaklaşımında, dönüşüm modellemeyi ilişkilendirmeniz gerekir. Bu veri sınıfı, eşlemeleri saklar Bir varlığın örnekleri ile başka bir varlığın örnekleri arasında, yerleştirilmiş nesneler'i tıklayın. Sorgu yöntemleriniz, daha sonra bu veri sınıfını kullanmanız gerekir.
Örneğin, kitaplık kullanıcılarını temsil eden bir UserBook
veri sınıfı tanımlayabilirsiniz.
kontrol edebilir ve bu kitapların listesini almak için bir sorgu yöntemi
Veritabanından UserBook
örnek:
Kotlin
@Dao 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>> } 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(); } public class UserBook { public String userName; public String bookName; }
Çoklu eşleme dönüş türleri
Çoklu eşleme dönüş türü yaklaşımında, herhangi bir ek eşleme türü tanımlamanız gerekmez. veri sınıfları. Bunun yerine Şunun için çoklu eşleme dönüş türü: yöntemini belirleyin ve yöntem ile kurduğunuz ilişki SQL sorgunuzda varlıklarınız arasında otomatik olarak geçiş yapın.
Örneğin, aşağıdaki sorgu yöntemi User
ve Book
eşlemesini döndürür.
Kütüphane kullanıcılarını belirli kitaplara göz atmış olarak temsil eden örnekler:
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();
Yaklaşım belirleyin
Oda, bu yaklaşımların her ikisini de destekler. Bu nedenle, en iyi yaklaşıma sahip olmanız gerekir. Bu bölümde, iki nedenden birini tercih edebilirsiniz.
Orta düzey veri sınıfı yaklaşımı sayesinde karmaşık SQL yazmaktan kaçınabilirsiniz. ancak bu durum, ek veri sınıflarından bahsedeceğiz. Kısacası, çoklu harita dönüş türü Yaklaşımı, SQL sorgularınızın daha fazla iş yapmasını gerektirir ve orta düzeyde veriler daha fazla iş yapmak için kodunuzun kullanılmasını gerektirir.
Orta düzey veri sınıfları kullanmak için özel bir nedeniniz yoksa çoklu eşleme dönüş türü yaklaşımını kullanmanızı önerir. Şu konu hakkında daha fazla bilgi edinmek için: daha fazla bilgi için Bir çoklu eşleme.
Bu kılavuzun geri kalanında, orta düzey veri sınıfı yaklaşımı kullanabilirsiniz.
Yerleştirilmiş nesneler oluşturma
Bazen bir varlığı veya veri nesnesini
nesne birden fazla öğe içerse bile veritabanı mantığınızda tutarlı bir bütün
alanları. Böyle durumlarda,
@Embedded
ayrıştırmak istediğiniz bir nesneyi temsil eden ek açıklama
alt alanlara sahip olur. Ardından, Google Ads'de yerleşik olarak bulunan alanları
sütun oluşturabilirsiniz.
Örneğin, User
sınıfınız şunu içeren Address
türünde bir alan içerebilir:
street
, city
, state
ve
postCode
. Oluşturulan sütunları tabloda ayrı ayrı depolamak için tablodaki bir
User
sınıfındaki, Address
alanı
@Embedded
, olduğu gibi
aşağıdaki kod snippet'inde gösterilmektedir:
Kotlin
data class Address( val street: String?, val state: String?, val city: String?, @ColumnInfo(name = "post_code") val postCode: Int ) @Entity data class User( @PrimaryKey val id: Int, val firstName: String?, @Embedded val address: Address? )
Java
public class Address { public String street; public String state; public String city; @ColumnInfo(name = "post_code") public int postCode; } @Entity public class User { @PrimaryKey public int id; public String firstName; @Embedded public Address address; }
Bir User
nesnesini temsil eden tablo, aşağıdakilerin bulunduğu sütunları içerir
adlar: id
, firstName
, street
, state
, city
ve post_code
.
Bir öğede aynı türde birden çok yerleşik alan varsa her birini
değerini ayarlayarak
prefix
Ardından oda, sağlanan değeri her sütunun başına ekler
adını yazın.
Bire bir ilişkileri tanımlayın
İki varlık arasındaki bire bir ilişki, her öğenin örneği, alt öğenin tam olarak bir örneğine karşılık gelir varlık, tersi de geçerlidir.
Örneğin, kullanıcının bulunduğu bir kitaplığa sahip bir müzik yayın uygulaması düşünün.
şarkılarına yer verir. Her kullanıcının yalnızca bir kitaplığı ve her kullanıcının
tam olarak bir kullanıcıya karşılık gelir. Bu nedenle, bire bir
User
varlığı ile Library
varlığı arasındaki ilişki.
Bire bir ilişki tanımlamak için önce ikiniz için birer sınıf oluşturun varlıklarından oluşur. Varlıklardan biri diğer varlığın birincil anahtarına referans veren bir değişken eklemeyin.
Kotlin
@Entity data class User( @PrimaryKey val userId: Long, val name: String, val age: Int ) @Entity data class Library( @PrimaryKey val libraryId: Long, val userOwnerId: Long )
Java
@Entity public class User { @PrimaryKey public long userId; public String name; public int age; } @Entity public class Library { @PrimaryKey public long libraryId; public long userOwnerId; }
Kullanıcı listesini ve ilgili kitaplıkları sorgulamak için önce
bu iki varlık arasındaki birebir ilişki modelini kullanır. Bunu yapmak için bir
Her örneğin üst varlığın bir örneğini içerdiği yeni veri sınıfı ve
alt varlığın karşılık gelen örneğidir. @Relation
ekleyin
parentColumn
değeri şu şekilde ayarlanmış olarak alt varlık örneğine ek açıklama ekler:
ana varlığın birincil anahtar sütununun adı ve entityColumn
üst öğeye referans veren alt varlık sütununun adına ayarlayın
varlığa ilişkin bir birincil anahtardır.
Kotlin
data class UserAndLibrary( @Embedded val user: User, @Relation( parentColumn = "userId", entityColumn = "userOwnerId" ) val library: Library )
Java
public class UserAndLibrary { @Embedded public User user; @Relation( parentColumn = "userId", entityColumn = "userOwnerId" ) public Library library; }
Son olarak, DAO sınıfına tüm veri örneklerini döndüren bir yöntem ekleyin
üst varlık ile alt varlığı eşleyen sınıfıdır. Bu yöntem için
İki sorgu çalıştırmak için oda bulunduğundan, bu alana @Transaction
ek açıklamasını ekleyin
yöntemini kullanmanızı öneririz.
Kotlin
@Transaction @Query("SELECT * FROM User") fun getUsersAndLibraries(): List<UserAndLibrary>
Java
@Transaction @Query("SELECT * FROM User") public List<UserAndLibrary> getUsersAndLibraries();
Bire-çok ilişkileri tanımlama
İki varlık arasındaki bire-çok ilişki, her bir varlığın üst varlığın örneği, alt öğenin sıfır veya daha fazla örneğine karşılık gelir ancak alt varlığın her örneği yalnızca bir taneye karşılık gelebilir örneğidir.
Müzik yayın uygulaması örneğinde, kullanıcının düzenleme yapabildiğini varsayalım
şarkılarını oynatma listelerine dönüştürüyor. Her kullanıcı istediği sayıda oynatma listesi oluşturabilir.
Ancak her oynatma listesi tam olarak bir kullanıcı tarafından
oluşturulur. Dolayısıyla,
User
varlığı ile Playlist
varlığı arasında bire-çok bir ilişki.
Bire-çok bir ilişki tanımlamak için önce iki varlık için bir sınıf oluşturun. Bire bir ilişkide olduğu gibi, alt varlık ana varlığın birincil anahtarına verilen bir referanstır.
Kotlin
@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 )
Java
@Entity public class User { @PrimaryKey public long userId; public String name; public int age; } @Entity public class Playlist { @PrimaryKey public long playlistId; public long userCreatorId; public String playlistName; }
Kullanıcı listesini ve ilişkili oynatma listelerini sorgulamak için önce
bu iki varlık arasındaki bire-çok ilişki modelini kullanır. Bunu yapmak için
Her örneğin üst varlığın bir örneğini içerdiği yeni bir veri sınıfı ve
karşılık gelen tüm alt varlık örneklerinin listesi. @Relation
ekleyin
parentColumn
değeri şu şekilde ayarlanmış olarak alt varlık örneğine ek açıklama ekler:
ana varlığın birincil anahtar sütununun adı ve entityColumn
üst öğeye referans veren alt varlık sütununun adına ayarlayın
varlığa ilişkin bir birincil anahtardır.
Kotlin
data class UserWithPlaylists( @Embedded val user: User, @Relation( parentColumn = "userId", entityColumn = "userCreatorId" ) val playlists: List<Playlist> )
Java
public class UserWithPlaylists { @Embedded public User user; @Relation( parentColumn = "userId", entityColumn = "userCreatorId" ) public List<Playlist> playlists; }
Son olarak, DAO sınıfına tüm veri örneklerini döndüren bir yöntem ekleyin
üst varlık ile alt varlığı eşleyen sınıfıdır. Bu yöntem için
İki sorgu çalıştırmak için oda bulunduğundan, bu alana @Transaction
ek açıklamasını ekleyin
yöntemini kullanmanızı öneririz.
Kotlin
@Transaction @Query("SELECT * FROM User") fun getUsersWithPlaylists(): List<UserWithPlaylists>
Java
@Transaction @Query("SELECT * FROM User") public List<UserWithPlaylists> getUsersWithPlaylists();
Çoka-çok ilişkileri tanımlama
İki varlık arasındaki çoka-çok ilişki, her bir varlığın üst varlığın örneği, alt öğenin sıfır veya daha fazla örneğine karşılık gelir varlık, tersi de geçerlidir.
Müzik yayın uygulaması örneğinde, kullanıcı tanımlı oynatma listelerindeki şarkıları düşünün.
Her şarkı listesinde birçok şarkı bulunabilir ve her şarkı, birçok şarkıya ait olabilir.
farklı oynatma listeleri oluşturabilirsiniz. Dolayısıyla, bir çizelgede çoka-çok
Playlist
varlığı ile Song
varlığı arasında geçiş yapın.
Çoka-çok bir ilişki tanımlamak için önce ikisine ait her biri için bir sınıf oluşturun.
varlıklarından oluşur. Çoka-çok ilişkiler
diğer ilişki türlerinden farklıdır çünkü genellikle
alt varlıktaki ana varlığa atıfta bulunmalıdır. Bunun yerine,
ilişkisel bir varlığı temsil edecek sınıf veya çapraz referans
tablosunda gösterilir. Çapraz referans tablosu,
Bu tablodaki çoka-çok ilişkideki her bir varlığın birincil anahtarı
yardımcı olabilir. Bu örnekte, çapraz başvuru tablosundaki her bir satır
referans verilen Playlist
örneği ile Song
örneğinin bir eşlemesi
referans verilen şarkı listesinde yer alıyor.
Kotlin
@Entity data class Playlist( @PrimaryKey val playlistId: Long, val playlistName: String ) @Entity data class Song( @PrimaryKey val songId: Long, val songName: String, val artist: String ) @Entity(primaryKeys = ["playlistId", "songId"]) data class PlaylistSongCrossRef( val playlistId: Long, val songId: Long )
Java
@Entity public class Playlist { @PrimaryKey public long playlistId; public String playlistName; } @Entity public class Song { @PrimaryKey public long songId; public String songName; public String artist; } @Entity(primaryKeys = {"playlistId", "songId"}) public class PlaylistSongCrossRef { public long playlistId; public long songId; }
Sonraki adım, bu ilgili varlıkları nasıl sorgulamak istediğinize bağlıdır.
- Oynatma listelerini ve bu şarkıya karşılık gelen şarkıların listesini sorgulamak isterseniz
her oynatma listesinde tek bir
Playlist
nesnesi içeren yeni bir veri sınıfı oluşturun ve oynatma listesinde yer alan tümSong
nesnelerinin listesi. - Şarkıları ve bu şarkıya karşılık gelen şarkı listelerinin listesini sorgulamak isterseniz
Her biri, tek bir
Song
nesnesi ve bir liste içeren yeni bir veri sınıfı oluşturun Şarkının yer aldığıPlaylist
nesnelerin tümü
Her iki durumda da
associateBy
özelliğinin her birindeki @Relation
ek açıklamasına
bu sınıfları kullanarak ilişkiyi sağlayan çapraz referans varlığını
Playlist
varlığı ile Song
varlığı arasında.
Kotlin
data class PlaylistWithSongs( @Embedded val playlist: Playlist, @Relation( parentColumn = "playlistId", entityColumn = "songId", associateBy = Junction(PlaylistSongCrossRef::class) ) val songs: List<Song> ) data class SongWithPlaylists( @Embedded val song: Song, @Relation( parentColumn = "songId", entityColumn = "playlistId", associateBy = Junction(PlaylistSongCrossRef::class) ) val playlists: List<Playlist> )
Java
public class PlaylistWithSongs { @Embedded public Playlist playlist; @Relation( parentColumn = "playlistId", entityColumn = "songId", associateBy = @Junction(PlaylistSongCrossref.class) ) public List<Song> songs; } public class SongWithPlaylists { @Embedded public Song song; @Relation( parentColumn = "songId", entityColumn = "playlistId", associateBy = @Junction(PlaylistSongCrossref.class) ) public List<Playlist> playlists; }
Son olarak, sorgu işlevini kullanıma sunmak için DAO sınıfına en iyi uygulamaları paylaşacağım.
getPlaylistsWithSongs
: Bu yöntem veritabanını sorgular ve sonuçta ortaya çıkanPlaylistWithSongs
nesne.getSongsWithPlaylists
: Bu yöntem veritabanını sorgular ve sonuçta ortaya çıkanSongWithPlaylists
nesne.
Bu yöntemlerin her biri iki sorgu çalıştırmak için Oda gerektirir. Bu nedenle,
@Transaction
ek açıklamasını her iki yönteme de eklemenizi sağlar. Böylece,
İşlem atomik olarak gerçekleştirilir.
Kotlin
@Transaction @Query("SELECT * FROM Playlist") fun getPlaylistsWithSongs(): List<PlaylistWithSongs> @Transaction @Query("SELECT * FROM Song") fun getSongsWithPlaylists(): List<SongWithPlaylists>
Java
@Transaction @Query("SELECT * FROM Playlist") public List<PlaylistWithSongs> getPlaylistsWithSongs(); @Transaction @Query("SELECT * FROM Song") public List<SongWithPlaylists> getSongsWithPlaylists();
İç içe yerleştirilmiş ilişkileri tanımlama
Bazen, hepsi bir arada bulunan üç veya daha fazla tablodan oluşan bir kümeyi sorgulamanız gerekebilir. bir araya getirmektir. Bu durumda, iç içe yerleştirilmiş ilişkileri tanımlarsınız yardımcı olabilir.
Müzik yayın uygulaması örneğinde tüm müziklerinizin kullanıcıları, her kullanıcı için tüm oynatma listelerini ve her oynatma listesindeki tüm şarkıları her kullanıcı için geçerli olur. Kullanıcıların şu reklamverenle bire-çok ilişkisi vardır oynatma listeleri ve oynatma listelerinin çoka-çok ilişkisi vardır. şarkılar. Aşağıdaki kod örneğinde, bu sınıfları temsil eden sınıflar öğe türlerinin yanı sıra çoka-çok ilişkisine ilişkin çapraz referans tablosu da oynatma listeleri ve şarkılar arasında:
Kotlin
@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 ) @Entity data class Song( @PrimaryKey val songId: Long, val songName: String, val artist: String ) @Entity(primaryKeys = ["playlistId", "songId"]) data class PlaylistSongCrossRef( val playlistId: Long, val songId: Long )
Java
@Entity public class User { @PrimaryKey public long userId; public String name; public int age; } @Entity public class Playlist { @PrimaryKey public long playlistId; public long userCreatorId; public String playlistName; } @Entity public class Song { @PrimaryKey public long songId; public String songName; public String artist; } @Entity(primaryKeys = {"playlistId", "songId"}) public class PlaylistSongCrossRef { public long playlistId; public long songId; }
İlk olarak, ilk olarak kümenizdeki tablolardan ikisi arasındaki ilişkiyi
ve bir veri sınıfı ve
@Relation
ek açıklaması. İlgili içeriği oluşturmak için kullanılan
aşağıdaki örnekte çoka-çok modelleyen bir PlaylistWithSongs
sınıfı gösterilmektedir
Playlist
varlık sınıfı ile Song
varlık sınıfı arasındaki ilişki:
Kotlin
data class PlaylistWithSongs( @Embedded val playlist: Playlist, @Relation( parentColumn = "playlistId", entityColumn = "songId", associateBy = Junction(PlaylistSongCrossRef::class) ) val songs: List<Song> )
Java
public class PlaylistWithSongs { @Embedded public Playlist playlist; @Relation( parentColumn = "playlistId", entityColumn = "songId", associateBy = Junction(PlaylistSongCrossRef.class) ) public List<Song> songs; }
Bu ilişkiyi temsil eden bir veri sınıfı tanımladıktan sonra başka bir veri sınıfı oluşturun
ve kümenizdeki başka bir tablo arasındaki ilişkiyi modelleyen veri sınıfı
ilk ilişki sınıfı, "iç içe yerleştirme" bu yeni sürecin içindeki mevcut
bir. Aşağıdaki örnekte, bir UserWithPlaylistsAndSongs
sınıfı gösterilmektedir.
User
varlık sınıfı ile
PlaylistWithSongs
ilişki sınıfı:
Kotlin
data class UserWithPlaylistsAndSongs( @Embedded val user: User @Relation( entity = Playlist::class, parentColumn = "userId", entityColumn = "userCreatorId" ) val playlists: List<PlaylistWithSongs> )
Java
public class UserWithPlaylistsAndSongs { @Embedded public User user; @Relation( entity = Playlist.class, parentColumn = "userId", entityColumn = "userCreatorId" ) public List<PlaylistWithSongs> playlists; }
UserWithPlaylistsAndSongs
sınıfı, ilişkileri dolaylı olarak modeller
üç varlık sınıfı arasında bulunuyor: User
, Playlist
ve Song
. Bu
Şekil 1'de gösterilmiştir.
![UserWithOynatmaListeleriAndSongs, Kullanıcı ve
Oynatma Listesi arasındaki ilişkiyi modeller.
ve Şarkı.](https://developer.android.com/static/images/training/data-storage/room_nested_relationships.png?authuser=9&hl=tr)
Şekil 1. Şemadaki ilişki sınıflarının müzik yayın uygulaması örneği.
Grubunuzda daha fazla tablo varsa kalan her tablo ve modelleyen ilişki sınıfı arasındaki ilişki her tür ilişkiyi ele alalım. Bu yöntem, bir iç içe yerleştirilmiş bir zincir tablolar arasında ilişki kurmak için de kullanabilirsiniz.
Son olarak, dönüşüm gerçekleştiren sorgu işlevini kullanıma sunmak için DAO sınıfına
en iyi uygulamaları paylaşacağız. Bu yöntemde birden fazla sorgu çalıştırmak için Oda gerekir. Bu nedenle,
@Transaction
ek açıklaması
Böylece tüm işlem atomik olarak gerçekleşsin:
Kotlin
@Transaction @Query("SELECT * FROM User") fun getUsersWithPlaylistsAndSongs(): List<UserWithPlaylistsAndSongs>
Java
@Transaction @Query("SELECT * FROM User") public List<UserWithPlaylistsAndSongs> getUsersWithPlaylistsAndSongs();
Ek kaynaklar
Odadaki öğeler arasındaki ilişkileri tanımlama hakkında daha fazla bilgi edinmek için ek kaynakları inceleyin.
Örnekler
Videolar
- Oda'daki Yenilikler (Android Dev) Zirvesi '19)