iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >如何在Room中使用Kotlin API
  • 385
分享到

如何在Room中使用Kotlin API

2023-06-14 11:06:23 385人浏览 泡泡鱼
摘要

本篇文章给大家分享的是有关如何在Room中使用Kotlin api,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。定义数据库表在我们的数据库中仅有一个表,就是保存词汇的表。Wor

本篇文章给大家分享的是有关如何在Room中使用Kotlin api,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。

定义数据库

在我们的数据库中仅有一个表,就是保存词汇的表。Word 类代表表中的一条记录,并且它需要使用注解 @Entity。我们使用 @PrimaryKey 注解为表定义主键。然后,Room 会生成一个 sqlite 表,表名和类名相同。每个类的成员对应表中的列。列名和类型与类中每个字段的名称和类型一致。如果您希望改变列名而不使用类中的变量名称作为列名,可以通过 @ColumnInfo 注解来修改。

@Entity(tableName = "word_table")data class Word(@PrimaryKey @ColumnInfo(name = "word") val word: String)

我们推荐大家使用 @ColumnInfo 注解,因为它可以使您更灵活地对成员进行重命名而无需同时修改数据库的列名。因为修改列名会涉及到修改数据库模式,因而您需要实现数据迁移。

访问表中的数据

如需访问表中的数据,需要创建一个数据访问对象 (DAO)。也就是一个叫做 WorkDao 的接口,它会带有 @Dao 注解。我们希望通过它实现表级别的数据插入、删除和获取,所以数据访问对象中会定义相应的抽象方法。操作数据库属于比较耗时的 I/O 操作,所以需要在后台线程中完成。我们将把 Room 与 Kotlin 协程和 Flow 相结合来实现上述功能。

@Daointerface WordDao {    @Query("SELECT * FROM word_table ORDER BY word ASC")    fun getAlphabetizedWords(): Flow<List<Word>>    @Insert(onConflict = OnConflictStrategy.IGNORE)    suspend fun insert(word: Word)}

我们在视频 Kotlin Vocabulary 中介绍了 协程的相关基本概念, 在 Kotlin Vocabulary 另一个视频中则介绍了 Flow 相关的内容。

插入数据

要实现插入数据的操作,首先创建一个抽象的挂起函数,需要插入的单词作为它的参数,并且添加 @Insert 注解。Room 会生成将数据插入数据库的全部操作,并且由于我们将函数定义为可挂起,所以 Room 会将整个操作过程放在后台线程中完成。因此,该挂起函数是主线程安全的,也就是在主线程可以放心调用而不必担心阻塞主线程。

@Insertsuspend fun insert(word: Word)

在底层 Room 生成了 Dao 抽象函数的实现代码。下面代码片段就是我们的数据插入方法的具体实现:

@Overridepublic Object insert(final Word word, final Continuation<? super Unit> p1) {    return CoroutinesRoom.execute(__db, true, new Callable<Unit>() {      @Override      public Unit call() throws Exception {          __db.beginTransaction();          try {              __insertionAdapterOfWord.insert(word);              __db.setTransactionSuccessful();          return Unit.INSTANCE;          } finally {              __db.endTransaction();          }      }    }, p1);}

CoroutinesRoom.execute() 函数被调用,里面包含三个参数: 数据库、一个用于表示是否正处于事务中的标识、一个 Callable 对象。Callable.call() 包含处理数据库插入数据操作的代码。

如果我们看一下 CoroutinesRoom.execute() 的 实现,我们会看到 Room 将 callable.call() 移动到另外一个 CoroutineContext。该对象来自构建数据库时您所提供的执行器,或者默认使用 Architecture Components IO Executor。

查询数据

为了能够查询表数据,我们这里创建一个抽象函数,并且为其添加 @Query 注解,注解后紧跟 SQL 请求语句: 该语句从单词数据表中请求全部单词,并且以字母顺序排序

我们希望当数据库中的数据发生改变的时候,能够得到相应的通知,所以我们返回一个 Flow<List<Word>>。由于返回类型是 Flow,Room 会在后台线程中执行数据请求。

@Query(“SELECT * FROM word_table ORDER BY word ASC”)fun getAlphabetizedWords(): Flow<List<Word>>

在底层,Room 生成了 getAlphabetizedWords():

@Overridepublic Flow<List<Word>> getAlphabetizedWords() {  final String _sql = "SELECT * FROM word_table ORDER BY word ASC";  final RoomSQLiteQuery _statement = RoomSQLiteQuery.acquire(_sql, 0);  return CoroutinesRoom.createFlow(__db, false, new String[]{"word_table"}, new Callable<List<Word>>() {    @Override    public List<Word> call() throws Exception {      final Cursor _cursor = DBUtil.query(__db, _statement, false, null);      try {        final int _cursorIndexOfWord = CursorUtil.getColumnIndexOrThrow(_cursor, "word");        final List<Word> _result = new ArrayList<Word>(_cursor.getCount());        while(_cursor.moveToNext()) {        final Word _item;        final String _tmpWord;        _tmpWord = _cursor.getString(_cursorIndexOfWord);        _item = new Word(_tmpWord);        _result.add(_item);        }        return _result;      } finally {        _cursor.close();      }    }    @Override    protected void finalize() {      _statement.release();    }  });}

我们可以看到代码里调用了 CoroutinesRoom.createFlow(),它包含四个参数: 数据库、一个用于标识我们是否正处于事务中的变量、一个需要监听的数据库表的列表 (在本例中列表里只有 word_table) 以及一个 Callable 对象。Callable.call() 包含需要被触发的查询的实现代码。

如果我们看一下 CoroutinesRoom.createFlow() 的 实现代码,会发现这里同数据请求调用一样使用了不同的 CoroutineContext。同数据插入调用一样,这里的分发器来自构建数据库时您所提供的执行器,或者来自默认使用的 Architecture Components IO 执行器。

创建数据库

我们已经定义了存储在数据库中的数据以及如何访问他们,现在我们来定义数据库。要创建数据库,我们需要创建一个抽象类,它继承自 RoomDatabase,并且添加 @Database 注解。将 Word 作为需要存储的实体元素传入,数值 1 作为数据库版本。

我们还会定义一个抽象方法,该方法返回一个 WordDao 对象。所有这些都是抽象类型的,因为 Room 会帮我们生成所有的实现代码。就像这里,有很多逻辑代码无需我们亲自实现。

最后一步就是构建数据库。我们希望能够确保不会有多个同时打开的数据库实例,而且还需要应用的上下文来初始化数据库。一种实现方法是在类中添加伴生对象,并且在其中定义一个 RoomDatabase 实例,然后在类中添加 getDatabase 函数来构建数据库。如果我们希望 Room 查询不是在 Room 自身创建的 IO Executor 中执行,而是在另外的 Executor 中执行,我们需要通过调用 setQueryExecutor() 将新的 Executor 传入 builder。

compaNIOn object {  @Volatile  private var INSTANCE: WordRoomDatabase? = null  fun getDatabase(context: Context): WordRoomDatabase {    return INSTANCE ?: synchronized(this) {      val instance = Room.databaseBuilder(        context.applicationContext,        WordRoomDatabase::class.java,        "word_database"        ).build()      INSTANCE = instance      // 返回实例      instance    }  }}

测试 Dao

为了测试 Dao,我们需要实现 AndroidJUnit 测试来让 Room 在设备上创建 SQLite 数据库。

当实现 Dao 测试的时候,在每个测试运行之前,我们创建数据库。当每个测试运行后,我们关闭数据库。由于我们并不需要在设备上存储数据,当创建数据库的时候,我们可以使用内存数据库。也因为这仅仅是个测试,我们可以在主线程中运行请求。

@RunWith(AndroidJUnit4::class)class WordDaoTest {    private lateinit var wordDao: WordDao  private lateinit var db: WordRoomDatabase  @Before  fun createDb() {      val context: Context = ApplicationProvider.getApplicationContext()      // 由于当进程结束的时候会清除这里的数据,所以使用内存数据库      db = Room.inMemoryDatabaseBuilder(context, WordRoomDatabase::class.java)          // 可以在主线程中发起请求,仅用于测试。          .allowMainThreadQueries()          .build()      wordDao = db.wordDao()  }  @After  @Throws(IOException::class)  fun closeDb() {      db.close()  }...}

要测试单词是否能够被正确添加到数据库,我们会创建一个 Word 实例,然后插入数据库,然后按照字母顺序找到单词列表中的第一个,然后确保它和我们创建的单词是一致的。由于我们调用的是挂起函数,所以我们会在 runBlocking 代码块中运行测试。因为这里仅仅是测试,所以我们无需关心测试过程是否会阻塞测试线程。

@Test@Throws(Exception::class)fun insertAndGetWord() = runBlocking {    val word = Word("word")    wordDao.insert(word)    val allWords = wordDao.getAlphabetizedWords().first()    assertEquals(allWords[0].word, word.word)}

除了本文所介绍的功能,Room 提供了非常多的功能性和灵活性,远远超出本文所涵盖的范围。比如您可以指定 Room 如何处理数据库冲突、可以通过创建 TypeConverters 存储原生 SQLite 无法存储的数据类型 (比如 Date 类型)、可以使用 JOIN 以及其它 SQL 功能实现复杂的查询、创建数据库视图、预填充数据库以及当数据库被创建或打开的时候触发特定动作。

以上就是如何在Room中使用Kotlin API,小编相信有部分知识点可能是我们日常工作会见到或用到的。希望你能通过这篇文章学到更多知识。更多详情敬请关注编程网精选频道。

--结束END--

本文标题: 如何在Room中使用Kotlin API

本文链接: https://www.lsjlt.com/news/270558.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 如何在Room中使用Kotlin API
    本篇文章给大家分享的是有关如何在Room中使用Kotlin API,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。定义数据库表在我们的数据库中仅有一个表,就是保存词汇的表。Wor...
    99+
    2023-06-14
  • Room Kotlin API的使用入门教程
    目录定义数据库表访问表中的数据插入数据查询数据创建数据库测试 DaoRoom 是 SQLite 的封装,它使 Android 对数据库的操作变得非常简单,也是迄今为止我最喜欢的 Je...
    99+
    2024-04-02
  • 如何在Django中使用API?
    好的,以下是文章内容: Django是一个流行的Python Web框架,它提供了许多内置的功能和库,使得开发Web应用变得更加容易。其中一个内置的功能是Django的REST框架,它让我们能够轻松地创建和使用API。 本文将会介绍如何在D...
    99+
    2023-06-29
    编程算法 django api
  • dataclass与objectclass函数如何在Kotlin中使用
    这期内容当中小编将会给大家带来有关dataclass与objectclass函数如何在Kotlin中使用,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。Kotlin基础教程之dataclass,object...
    99+
    2023-05-31
    kotlin objectclass dataclass
  • 如何在Java中使用NPM API?
    在Java中使用NPM API可以让开发人员更加便捷地管理和使用NPM包,而不需要离开Java开发环境。本文将介绍如何在Java中使用NPM API,并附带演示代码。 一、NPM API简介 NPM API是一个基于RESTful的API,...
    99+
    2023-09-26
    api npm 关键字
  • 如何在HTML5中使用Geolocation API
    这期内容当中小编将会给大家带来有关如何在HTML5中使用Geolocation API,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。Geolocation是HTML5标准下的一个Web API,利用它可以...
    99+
    2023-06-09
  • Docker API如何在Golang中使用
    Docker API如何在Golang中使用?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。安装 SDK通过下面的命令就可以安装 SDK 了:go get g...
    99+
    2023-06-14
  • 如何在Python中使用shell API?
    Python是一种流行的编程语言,它具有简单易学、高效灵活、可扩展性强等优点,因此越来越多的人选择使用Python来进行编程工作。在Python中,我们可以使用shell API来执行shell命令,这样就可以让Python具有更强大的功能...
    99+
    2023-10-16
    关键字 shell api
  • Android使用Kotlin API实践WorkManager
    目录WorkManager 基础 使 Worker 开始执行任务 但是如果我希望进行异步操作怎么办? WorkManager 提供了一系列 API 可以更加便捷地规划异步任务,即使在...
    99+
    2024-04-02
  • Android Jetpack中Room的使用
    Room Room主要分三个部分 database、dao和实体类entity Entity entity实体类定义时需要用到@Entity(tableName = "student...
    99+
    2024-04-02
  • 如何在PHP中使用NumPy Load API?
    在本文中,我们将介绍如何在PHP中使用NumPy Load API。NumPy是一个Python库,用于科学计算和数值分析,提供了强大的数组操作和数学函数,可以用于线性代数、傅里叶变换和随机数生成等任务。NumPy Load API是Num...
    99+
    2023-08-28
    api numpy load
  • kotlin中::双冒号如何使用
    这篇文章主要介绍“kotlin中::双冒号如何使用”,在日常操作中,相信很多人在kotlin中::双冒号如何使用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”kotlin中::双冒号如何使用”的疑惑有所帮助!...
    99+
    2023-07-06
  • jpa与 kotlin如何正确的在spring boot中使用
    今天就跟大家聊聊有关 jpa与 kotlin如何正确的在spring boot中使用,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。kotlin里面的data class来创建enti...
    99+
    2023-05-31
    springboot kotlin jpa
  • 如何在PHP中使用实时Path API?
    当今的Web应用程序需要实时地获取和处理数据,Path API是一种强大的工具,它可以帮助开发人员轻松地实现实时数据处理功能。在本文中,我们将介绍如何在PHP中使用实时Path API。 Path API是一个可以与实时数据进行交互的API...
    99+
    2023-07-09
    实时 path api
  • 如何在PHP中使用NumPy数组API?
    NumPy是一个用于科学计算的Python库,它提供了一个强大的多维数组对象和一系列的函数操作这些数组。NumPy的强大之处在于它能够高效地进行向量化运算,这意味着它可以在数组上执行相同的操作而不需要使用for循环。在PHP中,我们可以使...
    99+
    2023-10-15
    numy 数组 api
  • 如何在Python中使用Apache存储API?
    Python是一门非常流行的编程语言,广泛应用于各种领域,包括数据分析、机器学习、Web开发等。在这些领域中,数据存储和管理是一个非常重要的问题。Apache存储API是一个非常流行的数据存储解决方案,本文将介绍如何在Python中使用Ap...
    99+
    2023-07-18
    api apache 存储
  • 如何在 Bash 中使用 Go API 函数?
    在Bash中使用Go API函数可以帮助我们更好地利用Go语言的强大功能。在本文中,我们将介绍如何在Bash中使用Go API函数,并提供一些示例代码。 一、安装Go语言环境 首先,我们需要在我们的系统上安装Go语言环境。如果您已经安装了G...
    99+
    2023-08-07
    函数 api bash
  • 如何使用 Python 编写 API 并在 Spring 中使用?
    Python 是一种十分流行的编程语言,它有着强大的数据处理和分析能力,同时也拥有丰富的库和工具,可以轻松地编写出高效、灵活的 API 接口。而 Spring 是一个基于 Java 开发的 Web 应用框架,它提供了很多方便的工具和组件,帮...
    99+
    2023-11-10
    spring linux api
  • 如何在kotlin+java项目中使用maven进行打包
    这期内容当中小编将会给大家带来有关如何在kotlin+java项目中使用maven进行打包,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。Java的特点有哪些Java的特点有哪些1.Java语言作为静态面向...
    99+
    2023-06-06
  • Kotlin中如何使用和配置Dagger2
    这篇文章主要介绍了Kotlin中如何使用和配置Dagger2,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。配置 Dagger2项目中使用 Dagger2 ,首先还是添加依赖。...
    99+
    2023-05-30
    kotlin dagger2
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作