前言

Room 是官方推出的一个在 SQLite 上提供抽象层的持久存储库,提供了强大而可靠的 SQL 对象映射能力,并且支持 LiveDataRxJava

在项目中添加以下依赖

    def room_version = "2.1.0-alpha04"def lifecycle_version = "2.0.0"def rxjava_version = '2.1.7'def rxandroid_version = '2.1.0'// Roomimplementation "androidx.room:room-runtime:$room_version"kapt "androidx.room:room-compiler:$room_version"implementation "androidx.room:room-rxjava2:$room_version"// RxJavaimplementation "io.reactivex.rxjava2:rxjava:$rxjava_version"implementation "io.reactivex.rxjava2:rxandroid:$rxandroid_version"// ViewModel and LiveDataimplementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version"implementation 'com.google.code.gson:gson:2.8.5'// 查看数据库implementation 'com.facebook.stetho:stetho-okhttp3:1.5.0'
复制代码

当异步查询数据的时候,返回的对象可以是一个 LiveData 或者 Flowable 。如:

    @Query("SELECT * FROM user")abstract fun getAllUsers(): Flowable<List<User>>@Query("SELECT * FROM user")abstract fun getAllUser(): LiveData<List<User>>
复制代码

当我们存储的实体类中包含 List ,如果按照普通的方式去定义 Entity。编译的时候就会报以下错误:

Cannot figure out how to save this field into database. You can consider adding a type converter for it.
复制代码

这是因为 Room 无法直接存储 List 类型的数据,接下来我们将解决这个问题。

实践

  • 假设一个 User 对象会有很多本喜欢的书籍,一般定义的 Entity 类是以下格式:

    
    @Entity(tableName = "user")
    data class User(@PrimaryKey(autoGenerate = true)@ColumnInfo(name = "id")val id: Int,@ColumnInfo(name = "name")val name: String,@ColumnInfo(name = "books")val books: List<Book>)data class Book(val bookName: String
    )
    复制代码
  • 目前的情况下,编译项目就会遇到前面提到的错误。我们可以借助 @TypeConverter 去转换任意对象。例如定义一个 BookConverters

    class BookConverters {@TypeConverterfun stringToObject(value: String): List<Book> {val listType = object : TypeToken<List<Book>>() {}.typereturn Gson().fromJson(value, listType)}@TypeConverterfun objectToString(list: List<Book>): String {val gson = Gson()return gson.toJson(list)}
    }
    复制代码
  • 在实体类中添加 @TypeConverters 注解

    @Entity(tableName = "user")
    @TypeConverters(BookConverters::class)
    data class User(@PrimaryKey(autoGenerate = true)@ColumnInfo(name = "id")val id: Int,@ColumnInfo(name = "name")val name: String,@ColumnInfo(name = "books")val books: List<Book>)data class Book(val bookName: String
    )复制代码

@TypeConverters

这个注解的作用,就是告诉 Room 可以使用哪些额外的类型转换器。

一般定义的转换器类格式都是固定的:

class AnyConverters {@TypeConverterfun stringToObject(value: String): List<Any> {val listType = object : TypeToken<List<Any>>() {}.typereturn Gson().fromJson(value, listType)}@TypeConverterfun objectToString(list: List<Any>): String {val gson = Gson()return gson.toJson(list)}
}
复制代码

使用 Facebook 推出的 Stetho 可以很方便的查看数据库中内容:

代码示例

参考资料

stackoverflow
官方文档

Android Room 之存储 Objects 中的 List相关推荐

  1. android读取工程目录下的文件,Android编程实现读取工程中的txt文件功能

    本文实例讲述了Android编程实现读取工程中的txt文件功能.分享给大家供大家参考,具体如下: 1. 众所周知,Android的res文件夹是用来存储资源的,可以在res文件夹下建立一个raw文件夹 ...

  2. 魅族的android m l,Android M 外部存储剖析

    这篇文章是建立在你已经对 Android 外部存储的基础知识有一定了解的基础之上,如果之前并不是太了解这个部分,阅读起来可能会比较费劲,可以先阅读参考下面文章:http://blog.csdn.net ...

  3. android 模拟器识别,一种基于符号的识别Android应用运行在模拟器中的方法与流程...

    本发明涉及一种基于符号的识别android应用运行在模拟器中的方法. 背景技术: 很多的移动应用都会使用一种基于lbs的地理围栏的技术(如移动打卡),某些用户为了突破这种围栏的限制,将移动应用运行在模 ...

  4. android SharedPreferences数据存储

    android  SharedPreferences数据存储 很多时候我们开发的软件需要向用户提供软件参数设置功能,例如我们常用的QQ,用户可以设置是否允许陌生人添加自己为好友.对于软件配置参数的保存 ...

  5. 005 Android之数据存储

    文章目录 Android文件系统 Android文件的访问权限 文件访问权限实例 数据存储方式 内部存储 内部存储实例 外部存储 Shared Preferences Shared Preferenc ...

  6. Android 文件的存储和加载

    Android 文件的存储和加载,主要用于请求网络中json文件的缓存,引入了一个简单的过期时间,供大家参考学习! 文件存储 1 private void saveLocal(String json, ...

  7. 在Android初次的前期学习中的二个小例子(2)

    Hello13:SQLite数据库 一.简述SQLite的概念和主要特性 SQLite是一个轻量级的关系型数据库,运算速度快,占用资源少,使用非常方便,支持SQL语法标准和数据库事务原则. 相对于Sh ...

  8. 编写程序,使用一维数组,模拟栈数据结构。 要求: 1、这个栈可以存储java中的任何引用类型的数据。 2、在栈中提供push方法模拟压栈。(栈满了,要有

    代码 /*第一题:编写程序,使用一维数组,模拟栈数据结构.要求:1.这个栈可以存储java中的任何引用类型的数据.2.在栈中提供push方法模拟压栈.(栈满了,要有提示信息.)3.在栈中提供pop方法 ...

  9. Android安全开发之WebView中的地雷

    0X01 About WebView 在Android开发中,经常会使用WebView来实现WEB页面的展示,在Activiry中启动自己的浏览器,或者简单的展示一些在线内容等.WebView功能强大 ...

最新文章

  1. 函数的渐近的界阶的比较
  2. opencv c++ 寻找矩形框_基于Python的OpenCV人脸检测!OpenCV太强了!
  3. UML中符号的意义(转)
  4. 'unicodeescape' codec can't decode bytes in position 16-17: malformed \N character escape
  5. mysql连接报错Access denied for user ‘root‘@‘localhost‘
  6. 定时任务:Java中Timer和TimerTask的使用
  7. 代画PCB及C语言编程
  8. java异步io_Java中的异步IO与异步请求处理
  9. 在 CSS 中,width 和 height 指的是内容区域的宽度和高度
  10. 用API实现串口异步读写
  11. python123电脑登录不了_python(14)- 简单练习:登录账户失败三次,账户自动锁定...
  12. 「零基础从零开始写VO视觉里程计」如何求解线性方程 Hdx=b?(7-)
  13. 2020.11.14--AE--图层八种形式、图层面板图标、查看器面板
  14. python列联表分析
  15. Python学习知识清单(基础+进阶)
  16. 手把手教你用Python画直方图
  17. 网络安全——病毒详解以及批处理01(自启动,修改密码 定时关机,蓝屏,进程关闭)
  18. openstack compute service list报错(HTTP 503)
  19. 网络流量分析详解(包含OSI七层模型、TCP协议及Wireshark工具用法)
  20. Gym环境分析及构建

热门文章

  1. Anaconda+tensorflow+keras的下载与安装
  2. Python3爬虫入门之Request库的使用
  3. 第十一周学习进度报告
  4. 图解系列之JAVA执行过程
  5. opencvpython 段力辉是哪本书_OpenCV基础 | 1.python3.6+OpenCV4.0环境配置
  6. 宁波海曙区服务器维修,宁波市海曙区第二医院关于服务器(备份一体机) 1套的在线询价公告...
  7. JAVA中如何交换两个List集合的顺序呢?
  8. windows下的安装与使用curl实现命令行访问Web网站
  9. Git Tag及使用
  10. Synergy,一个软件团队质量改进之路之一 --- 规划