Uygulamanızın verilerini depolamak için Oda kalıcılık kitaplığını kullandığınızda, veri erişimi nesneleri veya DAO'lar tanımlayarak depolanan verilerle etkileşime geçersiniz. Her DAO, uygulamanızın veritabanına soyut erişim sunan yöntemler içerir. Derleme sırasında Room, tanımladığınız DAO'ların uygulamalarını otomatik olarak oluşturur.
Uygulamanızın veritabanına sorgu oluşturucular veya doğrudan sorgular yerine erişmek için DAO'ları kullanarak kritik bir mimari ilkesi olan endişelerin ayrılmasını koruyabilirsiniz. DAO'lar, uygulamanızı test ederken veritabanı erişimiyle ilgili taklit yapmanızı da kolaylaştırır.
Bir DAO'nun anatomisi
Her DAO'yu bir arayüz veya soyut sınıf olarak tanımlayabilirsiniz. Temel kullanım alanları için genellikle bir arayüz kullanırsınız. Her iki durumda da DAO'larınıza her zaman @Dao
ek açıklaması eklemeniz gerekir. DAO'ların mülkleri yoktur, ancak uygulamanızın veritabanındaki verilerle etkileşim için bir veya daha fazla yöntem tanımlarlar.
Aşağıdaki kod, bir Oda veritabanında User
nesneleri ekleme, silme ve seçme yöntemlerini tanımlayan basit bir DAO örneğidir:
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(); }
Veritabanı etkileşimlerini tanımlayan iki tür DAO yöntemi vardır:
- SQL kodu yazmadan veritabanınıza satır eklemenize, güncellemenize ve silmenize olanak tanıyan kullanışlı yöntemler.
- Veritabanıyla etkileşime geçmek için kendi SQL sorgunuzu yazmanıza olanak tanıyan sorgu yöntemleri.
Aşağıdaki bölümlerde, uygulamanızın ihtiyaç duyduğu veritabanı etkileşimlerini tanımlamak için her iki DAO yöntemi türünün nasıl kullanılacağı gösterilmektedir.
Kullanışlı yöntemler
Oda, SQL ifadesi yazmanıza gerek kalmadan basit ekleme, güncelleme ve silme işlemlerini gerçekleştiren yöntemleri tanımlamaya yönelik, kolaylık notları sunar.
Daha karmaşık eklemeler, güncellemeler veya silme işlemleri tanımlamanız ya da veritabanındaki verileri sorgulamanız gerekiyorsa bunun yerine bir sorgu yöntemi kullanın.
Ekle
@Insert
ek açıklaması, parametrelerini veritabanındaki uygun tabloya ekleyecek yöntemler tanımlamanızı sağlar. Aşağıdaki kod, veritabanına bir veya daha fazla User
nesnesi ekleyen geçerli @Insert
yöntemlerine örnekler göstermektedir:
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
yönteminin her parametresi, @Entity
ek açıklamasına sahip bir Oda veri varlığı sınıfının örneği veya her biri bir veritabanını işaret eden veri varlık sınıfı örneklerinin bir koleksiyonu olmalıdır. Bir @Insert
yöntemi çağrıldığında Room, iletilen her varlık örneğini ilgili veritabanı tablosuna ekler.
@Insert
yöntemi tek bir parametre alırsa long
değerini döndürebilir. Bu, eklenen öğe için yeni rowId
değeridir. Parametre bir dizi veya koleksiyonsa bunun yerine, her değeri eklenen öğelerden biri için rowId
olacak şekilde, long
değerlerinden oluşan bir dizi veya koleksiyon döndürün. rowId
değerlerini döndürme hakkında daha fazla bilgi edinmek için @Insert
ek açıklamasıyla ilgili referans belgelerine ve satır kimliği tablolar için SQLite dokümanlarına bakın.
Güncelle
@Update
ek açıklaması, bir veritabanı tablosundaki belirli satırları güncelleyen yöntemler tanımlamanızı sağlar. @Insert
yöntemleri gibi @Update
yöntemleri de veri varlığı örneklerini parametre olarak kabul eder.
Aşağıdaki kod, veritabanındaki bir veya daha fazla User
nesnesini güncellemeye çalışan bir @Update
yöntemi örneğini gösterir:
Kotlin
@Dao interface UserDao { @Update fun updateUsers(vararg users: User) }
Java
@Dao public interface UserDao { @Update public void updateUsers(User... users); }
Oda, geçirilen varlık örneklerini veritabanındaki satırlarla eşleştirmek için birincil anahtarı kullanır. Aynı birincil anahtara sahip bir satır yoksa Oda değişiklik yapmaz.
@Update
yöntemi, isteğe bağlı olarak başarıyla güncellenen satır sayısını belirten bir int
değeri döndürebilir.
Sil
@Delete
ek açıklaması, bir veritabanı tablosundaki belirli satırları silen yöntemler tanımlamanızı sağlar. @Insert
yöntemleri gibi @Delete
yöntemleri de veri varlığı örneklerini parametre olarak kabul eder.
Aşağıdaki kod, bir veya daha fazla User
nesnesini veritabanından silmeye çalışan bir @Delete
yöntemi örneğini gösterir:
Kotlin
@Dao interface UserDao { @Delete fun deleteUsers(vararg users: User) }
Java
@Dao public interface UserDao { @Delete public void deleteUsers(User... users); }
Oda, geçirilen varlık örneklerini veritabanındaki satırlarla eşleştirmek için birincil anahtarı kullanır. Aynı birincil anahtara sahip bir satır yoksa Oda değişiklik yapmaz.
@Delete
yöntemi, isteğe bağlı olarak başarıyla silinen satır sayısını belirten bir int
değeri döndürebilir.
Sorgu yöntemleri
@Query
ek açıklaması, SQL ifadeleri yazmanıza ve bunları DAO yöntemleri olarak göstermenize olanak tanır. Uygulamanızın veritabanından veri sorgulamak için veya daha karmaşık ekleme, güncelleme ve silme işlemleri yapmanız gerektiğinde bu sorgu yöntemlerini kullanın.
Oda, derleme zamanında SQL sorgularını doğrular. Bu, sorgunuzla ilgili bir sorun olduğunda çalışma zamanı hatası yerine bir derleme hatasının oluştuğu anlamına gelir.
Basit sorgular
Aşağıdaki kod, veritabanındaki tüm User
nesnelerini döndürmek için basit bir SELECT
sorgusu kullanan bir yöntemi tanımlar:
Kotlin
@Query("SELECT * FROM user") fun loadAllUsers(): Array<User>
Java
@Query("SELECT * FROM user") public User[] loadAllUsers();
Aşağıdaki bölümlerde, bu örneğin tipik kullanım alanları için nasıl değiştirileceği gösterilmektedir.
Tablo sütunlarının bir alt kümesini döndürme
Çoğu zaman, yalnızca sorguladığınız tablodaki sütunların bir alt kümesini döndürmeniz gerekir. Örneğin, kullanıcı arayüzünüz bir kullanıcıyla ilgili her ayrıntı yerine yalnızca kullanıcının adını ve soyadını görüntüleyebilir. Kaynakları kaydetmek ve sorgunuzun yürütülmesini kolaylaştırmak için yalnızca ihtiyacınız olan alanları sorgulayın.
Oda, sonuç sütunu grubunu döndürülen nesneyle eşleştirebildiğiniz sürece sorgularınızın herhangi birinden basit bir nesne döndürmenize olanak tanır. Örneğin, kullanıcının adını ve soyadını içerecek şekilde aşağıdaki nesneyi tanımlayabilirsiniz:
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; }
Ardından, sorgu yönteminizden bu basit nesneyi döndürebilirsiniz:
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();
Room, sorgunun first_name
ve last_name
sütunları için değer döndürdüğünü ve bu değerlerin NameTuple
sınıfındaki alanlarla eşlenebileceğini anlar. Sorgu, döndürülen nesnedeki bir alanla eşleşmeyen bir sütun döndürürse Oda bir uyarı gösterir.
Bir sorguya basit parametreler iletme
Çoğu zaman DAO yöntemlerinizin, filtreleme işlemlerini yürütebilmeleri için parametreleri kabul etmeleri gerekir. Oda, sorgularınızda yöntem parametrelerinin bağlama parametreleri olarak kullanılmasını destekler.
Örneğin, aşağıdaki kod belirli bir yaşın üzerindeki tüm kullanıcıları döndüren bir yöntemi tanımlar:
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);
Ayrıca, aşağıdaki kodda gösterildiği gibi birden çok parametre iletebilir veya bir sorguda aynı parametreye birden çok kez referans verebilirsiniz:
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);
Bir sorguya parametre koleksiyonu aktarma
DAO yöntemlerinizden bazıları, çalışma zamanına kadar bilinmeyen değişken sayıda parametre iletmenizi gerektirebilir. Oda, bir parametrenin bir koleksiyonu temsil ettiğini anlar ve sağlanan parametre sayısına göre çalışma zamanında otomatik olarak genişletir.
Örneğin, aşağıdaki kod bir bölge alt kümesindeki tüm kullanıcılar hakkında bilgi döndüren bir yöntemi tanımlar:
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);
Birden çok tabloyu sorgulama
Sorgularınızdan bazıları, sonucu hesaplamak için birden fazla tabloya erişimi gerektirebilir. Birden fazla tabloya referans vermek için SQL sorgularınızda JOIN
ifadelerini kullanabilirsiniz.
Aşağıdaki kod, şu anda belirli bir kullanıcıya ödünç olarak alınmış kitapları döndürmek için üç tabloyu bir araya getiren bir yöntemi tanımlar:
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);
Tablodaki sütunların bir alt kümesini döndürme bölümünde açıklandığı gibi, birleştirilmiş birden çok tablodan sütunların bir alt kümesini döndürecek basit nesneler de tanımlayabilirsiniz. Aşağıdaki kod, kullanıcıların adlarını ve ödünç aldıkları kitapların adlarını döndüren bir yöntemle bir DAO tanımlar:
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; } }
Çoklu harita döndürme
Oda 2.4 ve üzeri sürümlerde, bir çoklu eşleme döndüren sorgu yöntemleri yazarak ek bir veri sınıfı tanımlamadan birden fazla tablodan da sütun sorgulayabilirsiniz.
Birden çok tabloyu sorgulama bölümündeki örneği inceleyin.
User
ve Book
örneklerinin eşlerini barındıran özel bir veri sınıfı örneklerinin listesini döndürmek yerine, doğrudan sorgu yönteminizden User
ve Book
eşlemelerini döndürebilirsiniz:
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();
Sorgu yönteminiz bir çoklu eşleme döndürdüğünde GROUP BY
yan tümcelerini kullanan sorgular yazarak SQL'in gelişmiş hesaplama ve filtreleme özelliklerinden faydalanmanızı sağlar. Örneğin, loadUserAndBookNames()
yönteminizi yalnızca üç veya daha fazla kitabı olan kullanıcıları geri döndürecek şekilde değiştirebilirsiniz:
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();
Nesnelerin tamamını eşlemeniz gerekmiyorsa sorgu yönteminizde bir @MapInfo
ek açıklamasındaki keyColumn
ve valueColumn
özelliklerini ayarlayarak sorgunuzdaki belirli sütunlar arasındaki eşlemeleri de döndürebilirsiniz:
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();
Özel iade türleri
Oda, diğer API kitaplıklarıyla entegrasyon için bazı özel iade türleri sunar.
Sayfalandırma kitaplığıyla sorguları sayfalandırdı
Oda, çağrı kitaplığı ile entegrasyon yoluyla sayfalara ayrılmış sorguları destekler. Oda 2.3.0-alpha01 ve daha yüksek sürümlerde DAO'lar, Sayfa 3 ile kullanılmak üzere PagingSource
nesnelerini döndürebilir.
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
için tür parametreleri seçme hakkında daha fazla bilgi edinmek istiyorsanız Anahtar ve değer türlerini seçme bölümüne bakın.
Doğrudan imleç erişimi
Uygulamanızın mantığı, döndürme satırlarına doğrudan erişim gerektiriyorsa aşağıdaki örnekte gösterildiği gibi, DAO yöntemlerinizi bir Cursor
nesnesi döndürecek şekilde yazabilirsiniz:
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); }
Ek kaynaklar
Oda DAO'larını kullanarak verilere erişme hakkında daha fazla bilgi edinmek için aşağıdaki ek kaynakları inceleyin: