room

本地数据存储:

  1. SharedPreference
  2. File
  3. Room Database -> SQLite3移动端的小型数据库 -> MySql数据库
  4. DataStore Coroutine
  5. Remote
    使用 Room 持久保留数据

依赖:
implementation(“androidx.room:room-runtime:2.5.2”)
annotationProcessor(“androidx.room:room-compiler:2.5.2”)
kapt(“androidx.room:room-compiler:2.5.2”)
implementation(“androidx.room:room-ktx:2.5.2”)
导入插件:id ‘kotlin-kapt’


概述

使用 Android Jetpack 的 Room 部分将数据保存到本地数据库
room 使用频率很高,只要使用缓存就需要 room

Room 是 Android 官方推出的持久性库,用于简化 SQLite 数据库的操作。
它提供了一个抽象层,使开发者可以更轻松地访问数据库,同时提供了编译时检查和类型安全的查询。
Room包含三个主要组件: Entity(实体)、 Dao(数据访问对象)和 Database(数据库)。
通过这些组件,开发者可以轻松地定义数据库表结构、执行数据库操作和管理数据库连接。
Room 的出现大大简化了 Android 开发中对数据库的操作,提高了开发效率。

Room 对 MySQL语句进行高度封装

数据库里面只能存放基本的数据类型
integer bool char(20) varchar float double long bytes

三个主要组件

Room 由三个主要组件组成:

  1. Entity :表示数据库中的表结构,每个 Entity 对应数据库中的一张表。(数据实体)
  • 表名:类名
  • 字段:属性
  1. DAO (Data Access Object) :定义了对数据库进行操作的方法,通过DAO可以执行 CRUD 操作。
  • 分离业务层(应用)和持久化层(数据库)
  • 提供您的应用可用于查询、更新、插入和删除数据库中的数据的方法
  1. Database :表示整个数据库,包含了 Entity 和 DAO 的定义,并且提供了获取数据库实例的方法。用于保存数据库并作为应用持久性数据底层连接的主要访问点。(数据库类)

通过使用 Room ,开发者可以更加方便地进行数据库操作,同时避免了手动编写SQL语句的繁琐和错误。
Room 还提供了 LiveData 和 RxJava 等功能,可以方便地处理数据库中数据的变化和异步操作。

实现实例步骤

(0)导入依赖

(1)数据实体 Entity(创建表)

是一个 data clas

如果类名和在数据库中的表名不同:
@Entity(tableName = "picture table")
如果属性名和在数据库中的列名不同:
@ColumnInfo(name = "first_name")
标识主键:
@PrimaryKey(autoGenerate = true)

每个实例都代表应用数据库中 picture_table 表中的一行

1
2
3
4
5
6
7
8
9
10
@Entity(tableName = "picture_table")
data class Picture(
@PrimaryKey(autoGenerate = true) //主键自增长
val pid:lnt
var name:String
var time:String
var url: Int,
val thumbnail:Bitmap
)

(2)数据访问对象(DAO)

是一个 interface 接口

DAO 数据访问层,直接操作数据库表,进行增删改查等操作。

提供了app的其余部分与 Picture 表中的数据交互的方法。
使用 @Dao 注解

每个 DAO 定义为一个 接口 ,定义了一个或多个方法,可用于与应用数据库中的数据进行交互。

数据库的相关操作都是比较好使的,都放在协程中操作

@Insert 插入
@Updata 更新
@Delete 删除
@Query(“查询语句”) 查询

(无需实现 编译器自动完成)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Dao
interface PictureDao{
@Insert(onConflict = OnConflictStrategy.IGNORE)
suspend fun insertPicture(picture: Picture)

@Delete //删除多个
suspend fun deleteAll(pictures: List<Picture>)

@Delete //删除单个
suspend fun deletePicture(picture: Picture)

@Update
suspend fun updatePicture(picture: Picture)

@Query("select * from picture table")
fun queryPictures():LiveData<List<Picture>>
//or
//fun queryPictures():Flow<List<Picture>>
}

(3)数据库(Database)

是一个 abstract 抽象类

定义了用于保存数据库的类

  • 该类必须带有 @Database 注解,该注解包含列出所有与数据库关联的数据实体的 entities 数组。
  • 该类必须是一个抽象类 ,用于扩展 RoomDatabase
  • 对于与数据库关联的每个 DAO 类,数据库类必须定义一个具有零参数的抽象方法 ,并返回 DAO 类的实例

@TypeConverters() 是一个用于 Room 数据库库的注解,用于
指定将自定义数据类型转换为数据库可识别的数据类型的转换器。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
@Database(entities = [User::class], version = 1,exportSchema = false)

@TypeConverters(BitmapConverter::class)

abstract class PictureDatabase : RoomDatabase() { //抽象类 实现类由编译器完成
//获取PictureDao对象的抽象方法
abstract fun userDao(): PictureDao

//提供单例 数据库对象只能有一个
companion object{
private var database:PictureDatabase? = null

fun db():PictureDatabase{
if (database != null) return database!!
synchronized(this){
if (database == null){
database = Room.databaseBuilder(
Helper.mContextget()!!,
PictureDatabase::class.java,
"picture.db"
).build()
}
}
return database!!
}
}
}

数据类型转换类
数据类型转换方法用 @TypeConverter 标注

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class BitmapConverter{
//Bitmap -> ByteArray

@TypeConverter
fun bitmapToByteArray(bitmap: Bitmap):ByteArray{
ByteArrayOutputStream().use { baos ->
bitmap.compress(Bitmap.CompressFormat.JPEG, quality: 100,baos)
return baos.toByteArray()
}
}

//ByteArray -> Bitmap
@TypeConverter
fun byteArrayToBitmap(byteArray: ByteArray): Bitmap {
return BitmapFactory.decodeByteArray(byteArray, 0, byteArray.size)
}
}

(4)Repository 仓库

Repository(仓库)主要是针对数据进行操作,包括对不同类型数据库(如mysqsl、redis、mongodb等)中的数据进行整合。
业务层(ViewModel)应该直接和 Repository 打交道。

  1. 数据库
  2. 文件
  3. 网络
  4. 自己的数据

Repository是中转站,统一的数据库存取方法,
对于外部来说,暴露的方法永远都是 Repository 中的方法,
如果突然有一天不想用这个数据库了,想使用网络或者其他的数据库了,但是不影响外部调用 ,
只需要在 Repository 中将 DAO 换成网络或者其他数据库的的 DAO 即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
dass Repository {
private val dao = PictureDatabase.db().pictureDao()
suspend fun addPicture(picture: Picture){
dao.insertPicture(picture)
}
suspend fun loadDatas():List<Picture>{
return dao.queryPictures()
}
suspend fun deleteAll(pictures: List<Picture>){
dao.deleteAll(pictures)
}
suspend fun deletePicture(picture: Picture){
dao.deletePicture(picture)
}
suspend fun updatePicture(picture: Picture){
dao.updatePicture(picture)
}
}

如果数据库类不用单例,该怎么创建数据库对象?

1
2
3
4
5
Room.databaseBuilder(
AudioHelper.instance.context.
MusicDatabase::class .java,
name:"musicdb"
).build()I
Donate
  • Copyright: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.

扫一扫,分享到微信

微信分享二维码
  • Copyrights © 2023-2025 Annie
  • Visitors: | Views:

嘿嘿 请我吃小蛋糕吧~

支付宝
微信