Oda DAO'larını kullanarak verilere erişme

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:

Sana Özel

Codelab uygulamaları