MVVM的数据持久化(一)——ROOM的集成

MVVM数据持久化

之前我们分别介绍了MVVM框架的悲剧,项目搭建以及网络请求,接下来在这篇文章当中,我们来聊一聊MVVM数据持久化的问题,也就是我们常说的缓存

Room

Room持久库提供了一个SQLite抽象层,让你访问数据库更加稳健,提升数据库性能。 简介地址 https://developer.android.google.cn/training/data-storage/room/ Room在SQLite上提供了一个抽象层,以便在发挥SQLite能力的同时允许流畅的数据库访问,最主要的是它让SQLiteDatabase的使用变得简单,大大减少了重复的代码,并且把SQL查询的检查放在了编译时。而且还可以和RxJava配合使用的十分契合。

Room有3个主要的组件
Database:

包含数据库持有者,并充当与应用程序持久化的、关系型的数据的底层连接的主要访问点。 用@Database注解的类应满足以下条件: 是一个继承RoomDatabase的抽象类。 在注释中包含与数据库相关联的实体列表。 包含一个具有0个参数的抽象方法,并返回用@Dao注释的类。 在运行时,您可以通过调用Room.databaseBuilder()或Room.inMemoryDatabaseBuilder()获取数据库实例。

Entity:

表示数据库内的表。

DAO:

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

以及这三者之间的关系图:

三者关系图

加入依赖

以上简单的介绍了一下Room 下面我们着重介绍如何在我们的框架当中使用 首先加入依赖

    implementation 'android.arch.persistence.room:runtime:1.1.1'
    implementation 'android.arch.persistence.room:rxjava2:1.1.1'
    kapt 'android.arch.persistence.room:compiler:1.1.1'

看过之前文章的同学们,可以直接放在config.gradle当中,方便统一管理。

 dependVersion = [
 room_version       : '1.1.1'
 ]
      roomLib = [room_runtime: "android.arch.persistence.room:runtime:$dependVersion.room_version",
               room_rxjave2: "android.arch.persistence.room:rxjava2:$dependVersion.room_version"

    ]
    room = [ room: "android.arch.persistence.room:compiler:$dependVersion.room_version"]
    ]
    
     roomDeps = [roomLib.values()]
     roomDep = [room.values()]

在项目当中引用

    implementation project.ext.roomDeps
    kapt project.ext.roomDep

方便统一管理。 至此 我们就可以设计新的结构图如下:

结构图.png

根据结构图:

  1. View:Activity/Fragment
  2. ViewModel:使用RxJava处理数据
  3. Local Data:Room
  4. Remote Data:Retrofit

Room的使用

1.创建相应的Entity
Entity当中常用的几个属性
  1. Primary key 每个entity必须至少定义一个field作为主键(primary key)。即使只有一个field,你也必须用@PrimaryKey注释这个field。如果你想让Room为entity设置自增ID,你可以设置@PrimaryKey的autoGenerate属性。如果你的entity有一个组合主键,你可以使用@Entity注解的primaryKeys属性。

2.tableName Room默认把类名作为数据库的表名。如果你想用其它的名称,使用@Entity注解的tableName属性。

3.ColumnInfo Room默认把field名称作为数据库表的column名。如果你想让column有不一样的名称,为field添加@ColumnInfo属性。

4.Indices 和 unique 为了提高查询的效率,你可能想为特定的字段建立索引。要为一个entity添加索引,在@Entity注解中添加indices属性,列出你想放在索引或者组合索引中的字段。 有时候,某个字段或者几个字段必须是唯一的。你可以通过把@Index注解的unique属性设置为true来实现唯一性。

5.Embedded 有时你可能想把一个entity或者一个POJOs作为一个整体看待,即使这个对象包含几个field。这种情况下,你可以使用@Embedded注解,表示你想把一个对象分解为表的子字段。然后你就可以像其它独立字段那样查询这些嵌入的字段。

回到我们的项目当中,创建属于我们的Entity:

package yang.cehome.com.mvvmdemo.model.local.dao

import android.arch.persistence.room.Entity
import android.arch.persistence.room.PrimaryKey

/**
 * @author yangzc
 *  @data 2018/11/7 10:23
 *  @desc 创建Post的Entity
 *
 */
@Entity
data class PostEntity(
    val message: String,
    @PrimaryKey
    val nu: String,
    val ischeck: String,
    val condition: String,
    val com: String,
    val status: String,
    val state: String
)
2.创建Dao

相当于Retrofit中的api接口。

Dao负责操作数据库的方法,也就是说我们一些操作数据库的动作都是在这里完成的。不同的是我们不需要这些都用Dao类当中的注解来定义查询。

package yang.cehome.com.mvvmdemo.model.local.dao

import android.arch.persistence.room.Dao
import android.arch.persistence.room.Insert
import android.arch.persistence.room.OnConflictStrategy
import android.arch.persistence.room.Query
import io.reactivex.Single

/**
 * @author yangzc
 *  @data 2018/11/5 17:40
 *  @desc PostDao
 *
 */
@Dao
interface PostDao {
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    fun insetAll(postinfo: List<PostEntity>)


    @Insert(onConflict = OnConflictStrategy.REPLACE)
    fun inserttWeather(postinfo: PostEntity)

    @Query("SELECT * FROM postentity")
    fun getWeathInfo(): Single<PostEntity>

}
3.创建数据库

相当于创建RetrofitClient对象。

我们需要创建一个AppDatabase,这个类是包含了所以的Entity以及操作他们的DAO。这个类需要继承RoomDatabase的抽象类

package yang.cehome.com.mvvmdemo.model.local

import android.arch.persistence.room.Database
import android.arch.persistence.room.Room
import android.arch.persistence.room.RoomDatabase
import android.content.Context
import yang.cehome.com.mvvmdemo.model.local.dao.PostDao
import yang.cehome.com.mvvmdemo.model.local.dao.PostEntity

/**
 * @author yangzc
 *  @data 2018/11/5 18:21
 *  @desc 包含所有Entity以及操作它们的 DAO
 *
 */
@Database(entities = arrayOf(PostEntity::class), version = 1)
abstract class AppDatabase : RoomDatabase() {
    abstract fun WeatherDao(): PostDao

    companion object {
        @Volatile
        private var INSTANCE: AppDatabase? = null

        fun getInstance(context: Context): AppDatabase =
                INSTANCE ?: synchronized(this) {
                    INSTANCE ?: buildDatabase(context).also { INSTANCE = it }
                }

        private fun buildDatabase(context: Context) =
                Room.databaseBuilder(context.applicationContext,
                        AppDatabase::class.java, "app.db")
                        .build()
    }
}

Ok 至此Room集成完成

项目地址

https://github.com/yang0range/MVVM

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Java帮帮-微信公众号-技术文章全总结

day26.MySQL【Python教程】

15060
来自专栏农夫安全

代码审计之SQL注入漏洞

SQL注入: 我的理解很简单,能代入到数据库查询,且没有过滤,或过滤不严谨,就可以造成SQL注入 演示环境:linux+apache+...

37570
来自专栏ChaMd5安全团队

老司机带你过常规WAF

0x00 前言 最近看了不少关于WAF绕过的文章,想把理论深化到实践当中去,于是就有了您正在看的这篇文章,这篇文章分为两大部分,分别写的是SQL注入相关的WAF...

580110
来自专栏一枝花算不算浪漫

[Java面试三]JavaWeb基础知识总结.

78490
来自专栏Java帮帮-微信公众号-技术文章全总结

Jdbc知识点全整理,你值得拥有 ​(2)

1 DAO模式 DAO(Data Access Object)模式就是写一个类,把访问数据库的代码封装起来。DAO在数据库与业务逻辑(Service)之间。 l...

34540
来自专栏后台架构

Sphinx源码学习笔记(一):索引创建

  因为项目开发需要在游戏内部实现玩家名称的模糊查找功能,本身直接使用Sphinx配置mysql可以直接搭建一套模糊匹配的即可支持功能的实现。

53170
来自专栏用户画像

java 文件删除

23020
来自专栏逸鹏说道

SQL Server 存储过程的几种常见写法分析

最近发现还有不少做开发的小伙伴,在写存储过程的时候,在参考已有的不同的写法时,往往很迷茫, 不知道各种写法孰优孰劣,该选用那种写法,以及各种写法优缺点,本文以一...

43480
来自专栏Android学习之路

Android Room 持久化库

42470
来自专栏Kevin-ZhangCG

[ SSH框架 ] Hibernate框架学习之三

226110

扫码关注云+社区

领取腾讯云代金券