JetPack之使用 Room 将数据保存到本地数据库

一、ROOM简介

Room 在 SQLite 上提供了一个抽象层,以便在充分利用 SQLite 的强大功能的同时,能够流畅地访问数据库。

处理大量结构化数据的应用可极大地受益于在本地保留这些数据。最常见的用例是缓存相关数据。这样,当设备无法访问网络时,用户仍可在离线状态下浏览相应内容。设备重新连接到网络后,用户发起的所有内容更改都会同步到服务器。

由于 Room 负责为您处理这些问题,因此我们强烈建议您使用 Room(而不是 SQLite)。

二、添加ROOM库依赖

1) KOTLIN:

dependencies {
  def room_version = "2.2.6"

  implementation "androidx.room:room-runtime:$room_version"
  kapt "androidx.room:room-compiler:$room_version"

  // optional - Kotlin Extensions and Coroutines support for Room
  implementation "androidx.room:room-ktx:$room_version"

  // optional - Test helpers
  testImplementation "androidx.room:room-testing:$room_version"
}

2) JAVA:

dependencies {
  def room_version = "2.2.6"

  implementation "androidx.room:room-runtime:$room_version"
  annotationProcessor "androidx.room:room-compiler:$room_version"

  // optional - RxJava support for Room
  implementation "androidx.room:room-rxjava2:$room_version"

  // optional - Guava support for Room, including Optional and ListenableFuture
  implementation "androidx.room:room-guava:$room_version"

  // optional - Test helpers
  testImplementation "androidx.room:room-testing:$room_version"
}

三、ROOM组件

Room 包含 3 个主要组件:

  • 数据库:包含数据库持有者,并作为应用已保留的持久关系型数据的底层连接的主要接入点。

    使用 @Database 注释的类应满足以下条件:

    • 是扩展 RoomDatabase 的抽象类。
    • 在注释中添加与数据库关联的实体列表。
    • 包含具有 0 个参数且返回使用 @Dao 注释的类的抽象方法。

    在运行时,您可以通过调用 Room.databaseBuilder() 或 Room.inMemoryDatabaseBuilder() 获取 Database 的实例。

  • Entity:表示数据库中的表。

  • DAO:包含用于访问数据库的方法。

    扫描二维码关注公众号,回复: 16098102 查看本文章

应用使用 Room 数据库来获取与该数据库关联的数据访问对象 (DAO)。然后,应用使用每个 DAO 从数据库中获取实体,然后再将对这些实体的所有更改保存回数据库中。 最后,应用使用实体来获取和设置与数据库中的表列相对应的值。

Room 不同组件之间的关系如图 1 所示:

图 1.Room 架构图

四、示例

以下代码段包含具有一个实体和一个 DAO 的示例数据库配置。

1)KOTLIN

User

@Entity
    data class User(
        @PrimaryKey val uid: Int,
        @ColumnInfo(name = "first_name") val firstName: String?,
        @ColumnInfo(name = "last_name") val lastName: String?
    )
    

UserDao

 @Dao
    interface UserDao {
        @Query("SELECT * FROM user")
        fun getAll(): List<User>

        @Query("SELECT * FROM user WHERE uid IN (:userIds)")
        fun loadAllByIds(userIds: IntArray): List<User>

        @Query("SELECT * FROM user WHERE first_name LIKE :first AND " +
               "last_name LIKE :last LIMIT 1")
        fun findByName(first: String, last: String): User

        @Insert
        fun insertAll(vararg users: User)

        @Delete
        fun delete(user: User)
    }

AppDatabase

 @Database(entities = arrayOf(User::class), version = 1)
    abstract class AppDatabase : RoomDatabase() {
        abstract fun userDao(): UserDao
    }

创建上述文件后,您可以使用以下代码获取已创建的数据库的实例:

val db = Room.databaseBuilder(
                applicationContext,
                AppDatabase::class.java, "database-name"
            ).build()

2) JAVA

User

@Entity
    public class User {
        @PrimaryKey
        public int uid;

        @ColumnInfo(name = "first_name")
        public String firstName;

        @ColumnInfo(name = "last_name")
        public String lastName;
    }

UserDao

@Dao
    public interface UserDao {
        @Query("SELECT * FROM user")
        List<User> getAll();

        @Query("SELECT * FROM user WHERE uid IN (:userIds)")
        List<User> loadAllByIds(int[] userIds);

        @Query("SELECT * FROM user WHERE first_name LIKE :first AND " +
               "last_name LIKE :last LIMIT 1")
        User findByName(String first, String last);

        @Insert
        void insertAll(User... users);

        @Delete
        void delete(User user);
    }

AppDatabase

@Database(entities = {User.class}, version = 1)
    public abstract class AppDatabase extends RoomDatabase {
        public abstract UserDao userDao();
    }

创建上述文件后,您可以使用以下代码获取已创建的数据库的实例:

AppDatabase db = Room.databaseBuilder(getApplicationContext(),
            AppDatabase.class, "database-name").build();

注意:如果您的应用在单个进程中运行,在实例化 AppDatabase 对象时应遵循单例设计模式。每个 RoomDatabase 实例的成本相当高,而您几乎不需要在单个进程中访问多个实例。

如果您的应用在多个进程中运行,请在数据库构建器调用中包含 enableMultiInstanceInvalidation()。这样,如果您在每个进程中都有一个 AppDatabase 实例,可以在一个进程中使共享数据库文件失效,并且这种失效会自动传播到其他进程中 AppDatabase 的实例。

猜你喜欢

转载自blog.csdn.net/MYBOYER/article/details/113110080