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

Uygulamanızın verilerini depolamak için Oda kalıcılığı kitaplığını kullandığınızda veri erişimi nesnelerini veya DAO'ları tanımlayarak depolanan verilerle ilgili ayarları değiştirebilirsiniz. Her bir DAO uygulamanızın veritabanına soyut erişim sunan yöntemler içerir. Derleme sırasında Oda, tanımladığınız DAO'ların uygulamalarını otomatik olarak oluşturur.

Uygulamanızın veritabanına erişmek için sorgu oluşturucular veya doğrudan erişim yerine DAO'ları kullanarak ayrımını koruyarak dikkate alınması gereken bir nokta olan gösteriyoruz. DAO'lar, başka bir işlem yaparken veritabanı erişimiyle ilgili sahtecilik uygulamanızı test edin.

Bir DAO'nun anatomisi

Her DAO'yu bir arayüz veya soyut sınıf olarak tanımlayabilirsiniz. Temel genellikle bir arayüz kullanırsınız. Her iki durumda da DAO'larınıza @Dao ek açıklaması ekliyor. DAO'lar ancak bu öğeler etkileşim için bir veya daha fazla yöntem tanımlar uygulamanızın veritabanındaki verilerle uyumlu hale getirin.

Aşağıdaki kod, 2022'den itibaren geçerli olmak üzere Oda veritabanına User nesne ekleme, mevcut nesneleri silme ve seçme:

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:

  • Hesabınıza satır eklemenize, güncellemenize ve silmenize olanak tanıyan kullanışlı yöntemler SQL kodu yazmadan da kullanabilirsiniz.

Aşağıdaki bölümlerde, DAO yöntemlerinin her iki türünün de uygulamanızın ihtiyaç duyduğu veritabanı etkileşimlerini tanımlamanız gerekir.

Kolaylık yöntemleri

Oda, basit performans gösteren yöntemleri tanımlamak için kolaylık ek açıklamaları sunar ekleme, güncelleme ve silme işlemleri gerçekleştirebilirsiniz.

Daha karmaşık ekleme, güncelleme veya silme işlemleri tanımlamanız gerekiyorsa ya da Bunun yerine, veritabanındaki verileri sorgulamak için bir sorgu yöntemi kullanın.

Ekle

@Insert ek açıklaması şunları yapmanıza olanak tanır: parametrelerini aşağıdaki tablodaki uygun tabloya ekleyen yöntemleri tanımlayabilirsiniz. Aşağıdaki kodda, şu özelliklere sahip geçerli @Insert yöntemlerinden örnekler gösterilmektedir: veritabanına bir veya daha fazla User nesnesi ekleyin:

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, bir Odanın örneği olmalıdır veri varlığı sınıfı @Entity veya her biri veri varlığı sınıfı örneklerinden oluşan bir koleksiyon bir veri tabanına işaret eder. @Insert yöntemi çağrıldığında Oda, her bir yöntemi ekler Varlık örneğini ilgili veritabanı tablosuna aktarmıştır.

@Insert yöntemi tek bir parametre alırsa long döndürebilir değeri (bu, eklenen öğe için yeni rowId olur). Parametre bir bir dizi veya koleksiyon döndürür, ardından bir dizi veya koleksiyon döndürür yerine long değerleri (eklenen öğelerden biri için rowId olarak her değer) öğeler. rowId değerlerini döndürme hakkında daha fazla bilgi edinmek için referansa bakın. @Insert dokümanları ek açıklaması ve satır kimliği için SQLite dokümanları tabloları ile ilgili daha fazla bilgi edinin.

Güncelle

@Update ek açıklaması şunları yapmanıza olanak tanır: bir veritabanı tablosundaki belirli satırları güncelleyen yöntemler tanımlamalıdır. Beğenme @Insert ve @Update yöntem, veri varlığı örneklerini parametre olarak kabul eder. Aşağıdaki kod, bir @Update yönteminin bir örneğini veritabanındaki bir veya daha fazla User nesnesini güncelleyin:

Kotlin

@Dao
interface UserDao {
    @Update
    fun updateUsers(vararg users: User)
}

Java

@Dao
public interface UserDao {
    @Update
    public void updateUsers(User... users);
}

Oda, birincil tuşu ile eşleşti Varlık örneklerini veritabanındaki satırlara dönüştürür. Aynı oda başka bir değişiklik yapmaz.

@Update yöntemi, isteğe bağlı olarak sayıyı belirten bir int değeri döndürebilir. başarıyla güncellendi.

Sil

@Delete ek açıklaması şunları yapmanıza olanak tanır: Bir veritabanı tablosundaki belirli satırları silen yöntemler tanımlar. Beğenme @Insert ve @Delete yöntem, veri varlığı örneklerini parametre olarak kabul eder. Aşağıdaki kod, bir @Delete yönteminin bir örneğini veritabanından bir veya daha fazla User nesnesini silin:

Kotlin

@Dao
interface UserDao {
    @Delete
    fun deleteUsers(vararg users: User)
}

Java

@Dao
public interface UserDao {
    @Delete
    public void deleteUsers(User... users);
}

Oda, birincil tuşu ile eşleşti Varlık örneklerini veritabanındaki satırlara dönüştürür. Aynı oda başka bir değişiklik yapmaz.

@Delete yöntemi, isteğe bağlı olarakint satır sayısı başarıyla silindi.

Sorgu yöntemleri

@Query ek açıklaması şunları yapmanıza olanak tanır: SQL ifadeleri yazma ve bunları DAO yöntemleri olarak kullanıma sunma. Bu sorgu yöntemlerini kullanarak veya daha karmaşık işlemler yapmanız gerektiğinde ekleme, güncelleme ve silme işlemleri.

Oda, derleme sırasında SQL sorgularını doğrular. Yani, bir sorun olduğunda bir derleme hatası alırsanız çalışma zamanı hatası yerine derleme hatası oluşur.

Basit sorgular

Aşağıdaki kod, aşağıdaki kodu döndürmek için basit bir SELECT sorgusu kullanan bir yöntemi tanımlar: veritabanındaki tüm User nesneleri:

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 için nasıl değiştirileceği gösterilmektedir durumlarda işe yarar.

Bir tablo sütunlarının alt kümesini döndürme

Çoğu zaman, tablodaki sütunların yalnızca bir alt kümesini döndürmeniz gerekir görünür. Örneğin, kullanıcı arayüzünüz yalnızca ilk soyadına yer vermelisiniz. Kaydetmek için kaynaklarını kontrol edin ve sorgunuzun yürütülmesini kolaylaştırın; alanları bulun.

Oda, herhangi bir sorgudan yalnızca sonuç sütunları grubunu döndürülen nesneyle eşleyebilirsiniz. Örneğin, şu nesneyi kullanıcının adını ve soyadını içerecek şekilde tanımlayabilir:

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();

Oda, sorgunun first_name ve last_name sütuna sahip olduğunu ve bu değerlerin, NameTuple sınıf. Sorgu bir alanla eşleşmeyen bir sütun döndürürse Oda'da bir uyarı gösterilir.

Sorguya basit parametreler iletme

Çoğu zaman, DAO yöntemlerinizin uygun parametreleri Filtreleme işlemleri gerçekleştirmenize yardımcı olur. Oda, yöntem parametrelerinin bağlantı olarak kullanılmasını destekler parametreleridir.

Örneğin, aşağıdaki kod tüm kullanıcıları döndüren bir yöntemi tanımlar belirli bir yaşın üzerinde:

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, birden çok parametre iletebilir veya aynı parametrenin çoklu referans değerini aşağıdaki kodda gösterildiği gibi belirli değerler girin:

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);

Sorguya parametre koleksiyonu iletme

Bazı DAO yöntemleriniz, her bir DAO yöntemini uygulamak için bilinmeyen parametreler olduğunu varsayalım. Oda, bir parametrenin bir koleksiyonu temsil eder ve verilen parametre sayısını belirtir.

Örneğin, aşağıdaki kod her bir kullanıcı için bölgelerin bir alt kümesindeki tüm kullanıcılar:

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

Bazı sorgularınızda, yardımcı olur. Daha fazla referans için SQL sorgularınızda JOIN deyimlerini kullanabilirsiniz. bir tablo oluşturabilirsiniz.

Aşağıdaki kod, değer döndürülmesi için üç tabloyu birleştiren bir yöntemi tanımlar şu anda belirli bir kullanıcıya ödünç verilen kitaplar:

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);

Ayrıca, birden çok sütundan bir sütun alt kümesi döndürecek basit nesneler de tanımlayabilirsiniz. Tablonun bir alt kümesini döndürme sütunlar bölümüne gidin. Aşağıdaki kod, kullanıcıların adlarını ve ödünç aldıkları kitapların adlarını döndürür:

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 sonraki sürümlerde, herhangi bir öğe olmadan birden çok tablodan sütun sorgulayabilirsiniz. döndüren sorgu yöntemleri yazarak ek bir veri sınıfı tanımlamayı çoklu eşleme.

Birden çok tabloyu sorgulama bölümündeki örneği göz önünde bulundurun. Saklamakta olan özel bir veri sınıfına ait örneklerin listesini döndürmek yerine, User ve Book örneklerinden oluşan eşlemeleri döndürerek, User ve Doğrudan sorgu yönteminizden Book:

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 çoklu eşleme döndürdüğünde, birden fazla eşlemeyi kullanan GROUP BY yan tümceleri ile SQL'in sunduğu özelliklerden yararlanabilirsiniz. gelişmiş hesaplama ve filtrelemeyi kullanabilirsiniz. Örneğin, Yalnızca üç veya daha fazla kitabı olan kullanıcıları geri getirmek için loadUserAndBookNames() yöntemi çıkış tarihi:

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 değerini ayarlayarak sorgunuzdaki belirli sütunları keyColumn ve valueColumn özellikleri @MapInfo sorgu yöntemi:

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, başka bir API ile entegrasyon için bazı özel dönüş türleri sağlar kitaplıklar.

Sayfalara ayırma kitaplığıyla sayfalara ayrılmış sorgular

Oda, sayfalama ile entegrasyon aracılığıyla sayfalara ayrılmış sorguları destekler. kitaplığı'nda bulabilirsiniz. Oda 2.3.0-alpha01 ve daha yüksek olursa DAO'lar PagingSource nesne kullanılıyor sayfa 3 ile.

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 parametrelerini seçme hakkında daha fazla bilgi için bkz. Anahtar ve değer seçin seçin.

Doğrudan imleç erişimi

Uygulamanızın mantığı dönüş satırlarına doğrudan erişim gerektiriyorsa şunu yazabilirsiniz: Cursor döndürecek DAO yöntemleriniz nesnesini tanımlayın:

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şim hakkında daha fazla bilgi için aşağıdaki ek kaynaklar:

Örnekler

Codelab'ler