南昌网络公司,南昌网站建设,南昌APP开发,南昌小程序开发,南昌网络推广,南昌网络营销,网络公司,网络营销,网站推广,网站优化,网站制作,网站设计,网站建设,百度SEO优化,小程序开发,公众号开发,APP开发,全网推广,网站制作,网页制作,高端网站设计,高端网站建设,南顺网络,南顺科技
当前位置 南顺网络>> 知识拓展

Android数据库框架 Room的使用 AndroidX+Kotlin

简单来说,Room就是SQLite的一个封装,它充分利用注解,在编译期间自动生成查询的代码。我们要做的仅仅是在JavaBean上加入合适的注解,一个数据表就自动生成了。

  Room可以和RxJava,Guava配合使用,这里不做介绍(因为我也不会用)

本篇使用Android Studio 3.5.3,使用Kotlin插件


使用

准备步骤

要使用Room,需要在build.gradle里添加依赖库

在dependencies中声明:


def room_version = "2.2.1"

implementation "androidx.room:room-runtime:$room_version" // 运行时

    kapt "androidx.room:room-compiler:$room_version" // 解释器,用于在编译期间生成查询代码,不会编译进apk

    // 可选 - Kotlin Extensions and Coroutines support for Room

    implementation "androidx.room:room-ktx:$room_version"

使用kapt还需在build.gradle开头声明插件


apply plugin: 'kotlin-kapt'

1

除此之外,还需要指定注解处理器的参数


    android {

        //...

        defaultConfig {

            //...

            javaCompileOptions {

                annotationProcessorOptions {

                    arguments = [

                        "room.schemaLocation":"$projectDir/schemas".toString(),

                        "room.incremental":"true",

                        "room.expandProjection":"true"]

                }

            }

        }

    }


了解结构

Room 包含 3 个主要组件:


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

Entity:表示数据库中的表。

DAO:(Data Access Object)包含用于访问数据库的方法。


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


获取DAO

读写Entity对象

读写基本数据

RoomDatabase

App

Dao

Entities

画的有些丑,见谅


编写代码

编写Entity:

以User为例

@Entity // 默认以entity的类型名(小写)做为数据表名,或者指定 @Entity(tableName = "my_user")

data class User(

    @PrimaryKey(autoGenerate = true) // autoGenerate属性 将在插入时自动增加

    val uid: Int, // 默认以变量名小写为列名,驼峰式会自动转为下划线式

    

    @ColumnInfo(name = "user_name", index = true) // index 创建索引

    val userName: String,

    

    @ColumnInfo(name = "user_pass")

    val password: String,


@ColumnInfo(name = "nick_name")

    val nickName: String? // kotlin中的可空自动识别为sqlite的可空

)


编写Dao:

@Dao

interface UserDao {

// 查

@Query("SELECT * FROM user")

fun getAll(): List

@Query("SELECT * FROM user WHERE uid IN (:userIds)")

fun loadAllByIds(userIds: IntArray): List

@Query("SELECT * FROM user WHERE first_name LIKE :first AND " +

               "last_name LIKE :last LIMIT 1")

fun findByName(first: String, last: String): User


    @Query("SELECT COUNT(*) FROM `user` WHERE user_name = :userName")

    fun hasUser(userName: String): Boolean

// 增

@Insert

fun insertAll(vararg users: User)

// 删

@Delete

fun delete(user: User)


// 改

@Update

    fun updateUsers(vararg users: UserEntity): Int

    @Update

    fun updateUsers(users: List): Int // 这样重载也能识别

}


编写完上面的代码后,运行一下Ctrl+F9,就可以在app\build\generated\source\kapt\debug[package_name]\UserDao_Impl.java里看到生成的代码了


编写RoomDatabase:

@Database(entities = arrayOf(User::class), version = 1) // 定义版本号,便于升级管理

abstract class MyDatabase : RoomDatabase() {

    abstract fun userDao(): UserDao // 获取DAO

}


下面,就可以使用Room访问数据库了


val db = Room.databaseBuilder(

applicationContext,

    MyDatabase::class.java, "数据库文件名.db" // 创建数据库比较消耗资源,可以在Application加载时加载数据库,这样保证Database为单例加载模式,若App有多个进程,需要取消下面这行注释

)

//.enableMultiInstanceInvalidation()

.build()

val userDao = db.userDao()

var users = userDao.getAll() // 读取数据

for (user: User in users) {

// 修改数据

}

userDao.updateUsers(users) // 提交修改


进阶用法

从资源、文件填充数据

即复制某个现有的数据库到应用的database目录,然后使用它

这个比较简单,直接在创建Database实例时指定路径即可


Room.databaseBuilder(appContext, MyDatabase::class.java, "Sample.db")

    .createFromAsset("database/myapp.db") // 从assets目录复制

    .createFromFile(File("mypath")) // 从文件复制

    .build()

需要注意的是,Room在会验证数据库的结构是否与代码匹配,所以需要正确配置room.schemaLocation参数


升级数据库结构

编写 Migration 类,指定一个 startVersion 和 endVersion,如下


// 从version1升级到version2

val MIGRATION_1_2 = object : Migration(1, 2) {

override fun migrate(database: SupportSQLiteDatabase) {

database.execSQL("CREATE TABLE `Fruit` (`id` INTEGER, `name` TEXT, PRIMARY KEY(`id`))")

}

}


// 从version2升级到version3

val MIGRATION_2_3 = object : Migration(2, 3) {

override fun migrate(database: SupportSQLiteDatabase) {

database.execSQL("ALTER TABLE Book ADD COLUMN pub_year INTEGER")

}

}


// 从version1升级到version3

val MIGRATION_1_3 = object : Migration(1, 3) {

override fun migrate(database: SupportSQLiteDatabase) {

database.execSQL("CREATE TABLE `Fruit` (`id` INTEGER, `name` TEXT, PRIMARY KEY(`id`))")

database.execSQL("ALTER TABLE Book ADD COLUMN pub_year INTEGER")

}

}


这样在升级应用时,重新创建数据会保留原来的数据,并升级新的数据库结构

————————————————

版权声明:本文为CSDN博主「Gardel」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/baidu_24285051/article/details/103641020