一、什么是room
1.1 room简介
room是android jetpack组件库中的一部分,对sqlite进行了封装,简化了对sqlite数据库的操作,让开发者使用面向对象的方式(通过java/kotlin)来操作sqlite数据库,从而避免了编写大量繁琐的sql代码和解析数据。
1.2 三大核心组件
- entity(实体类):用于表示数据库表的数据结构。
- dao(data access object):用于定义数据库操作的方法。
- database(数据库类):用于创建数据库实例,并将 entity 和 dao 关联起来
二、集成room
在app下的build.gradle下添加:
//数据库创建成功,会有类似以下目录,以自己的为准\build\generated\source\kapt\release\com\xxx\xxx\drive\database\appdatabase_impl
def room_version = "2.5.1"
kapt "androidx.room:room-compiler:$room_version"
implementation "androidx.room:room-runtime:$room_version"
implementation "androidx.room:room-ktx:$room_version"
//这里注意:如果是某一个moudle中要使用room数据库,建议直接将库集成到moudle中的build.gradle中,博主这里遇到将root相关库集成到基类的build.gradle中,一直报错,提示生成数据库失败,上面的appdatabase_impl文件无法生成三、使用示例
3.1 创建实体类 (entity)
/**
* @description : localuploadrecord 数据库实体类,根据项目需求,定义自己的字段即可
*/
import androidx.room.columninfo
import androidx.room.entity
import androidx.room.primarykey
@entity(tablename = "upload_records")
data class localuploadrecord(
@primarykey(autogenerate = true)
val id: int? = null,
@columninfo(name = "phone_id")
val phoneid: string,//云机id
@columninfo(name = "phone_biz_id")
val phonebizid: string,//云机业务id
@columninfo(name = "user_id", index = true)
val userid: string,//登录返回的用户id
@columninfo(name = "file_name")
val filename: string,//文件名(含后缀)
@columninfo(name = "file_path")
val filepath: string,//文件路径
@columninfo(name = "phone_name")
val phonename: string,//云机名称
@columninfo(name = "file_status")
var filestatus: filestatus,//waiting, uploading, success, failed,installing,install_fail,install_success
@columninfo(name = "file_time")
val filetime: long,//文件操作时间-时间戳:毫秒
@columninfo(name = "file_size")
val filesize: long = 0,//文件大小,字节
@columninfo(name = "err_message")
var errmessage: string = "",
@columninfo(name = "reserved_field1")
var reservedfield1: string = "",//预留字段1
@columninfo(name = "reserved_field2")
var reservedfield2: string = "",//预留字段2
@columninfo(name = "reserved_field3")
var reservedfield3: string = "",//预留字段3
)各注解作用:
- @entity(tablename = "user-room"):标记这是一个数据库表,同时指定表名
- @primarykey(autogenerate = true):设置主键并启用自动生成
- @columninfo(name = "user_age"):设置列名
3.2 创建数据访问对象(dao)
创建一个接口定义数据库操作: @dao
/**
* @description : uploadrecorddao 创建数据访问对象(dao)
* @dao:标记这是一个数据访问对象接口
* @insert、@update、@delete:由room 提供的便捷注解,可以自动生成对应 sql
* @query:自定义 sql 查询,:参数名表示方法参数
*/
import androidx.room.dao
import androidx.room.delete
import androidx.room.insert
import androidx.room.query
import androidx.room.update
import kotlinx.coroutines.flow.flow
@dao
interface uploadrecorddao {
/**
* 插入一条数据
*/
@insert
fun insert(record: localuploadrecord): long
/**
* 删除最老的数据(按时间戳升序)
*/
@query("delete from upload_records where id in (select id from upload_records where user_id = :userid order by file_time asc limit :count)")
fun deleteoldest(userid: string,count:int)
/**
* 删除一条记录
*/
@delete
fun delete(record: localuploadrecord)
/**
* 更新一条记录
*/
@update
fun update(record: localuploadrecord)
/**
* 根据userid获取所有记录
*/
@query("select * from upload_records where user_id = :userid order by file_time desc")
fun getrecordsbyuser(userid: string): flow<list<localuploadrecord>>
/**
* 根据userid和filestatus获取记录
*/
@query("select * from upload_records where user_id = :userid and file_status in (:statuslist) order by file_time desc")
fun getrecordsbyuser(userid: string,statuslist: list<filestatus>):list<localuploadrecord>
/**
* 分页获取记录
*/
@query("select * from upload_records where user_id = :userid order by file_time desc limit :pagesize offset :offset")
fun getrecordsbyuserpaged(userid: string, pagesize: int, offset: int): list<localuploadrecord>
/**
* 根据userid查询记录数
*/
@query("select count(*) from upload_records where user_id = :userid")
fun getrecordcountbyuser(userid: string): int
/**
* 根据id查询一条记录
*/
@query("select * from upload_records where id = :id")
// suspend fun getrecordbyid(id: long): uploadrecord 低版本在dao中不能加suspend关键字,会报错,2.6.1中不会
fun getrecordbyid(id: long): localuploadrecord
/**
* 删除用户的所有数据
*/
@query("delete from upload_records where user_id = :userid")
fun deleteallbyuserid(userid: string): int
/**
* 根据id 批量删除数据
*/
@query("delete from upload_records where id in (:ids)")
fun deletebyids(ids: list<long>): int
}各注解作用:
- @dao:标记这是一个数据访问对象接口
- @insert、@update、@delete:由room 提供的便捷注解,可以自动生成对应 sql
- @query:自定义 sql 查询,:参数名表示方法参数
3.3 创建数据库类
创建一个抽象类用于扩展 roomdatabase:
/**
* @description : uploaddatabase 创建数据库类
* @database(entities = {myuser.class}, version = 1):标记数据库类,指定包含的表和版本号
* migration:定义数据库版本迁移逻辑
* 关于数据库迁移:
* 数据库迁移的核心作用是在修改数据库结构后(比如在实体类中添加新字段或是在库中添加新表),安全、无损地将旧版本数据库升级到新版本,同时保留用户的原有数据。
* 版本迁移逻辑:必须增加数据库的版本号,并提供一个migration对象来告诉room如何从旧版本正确迁移到新版本。
*/
import android.content.context
import androidx.room.database
import androidx.room.room
import androidx.room.roomdatabase
@database(
entities = [localuploadrecord::class],
version = 1,
exportschema = false
)
abstract class uploaddatabase : roomdatabase() {
abstract fun uploadrecorddao(): uploadrecorddao
companion object {
@volatile
private var instance: uploaddatabase? = null
fun getinstance(context: context): uploaddatabase {
return instance ?: synchronized(this) {
val instance = room.databasebuilder(
context.applicationcontext,
uploaddatabase::class.java,
"upload_database"
).build()
instance = instance
instance
}
}
}
}各注解作用:
- @database(entities = {myuser.class}, version = 1):标记数据库类,指定包含的表和版本号
- migration:定义数据库版本迁移逻辑
3.4 定义一个数据库管理类
import android.content.context
import android.util.log
import com.android.base.kits.klog
import com.yixin.cloudphone.drive.data.bean.pagedresult
import com.yixin.cloudphone.drive.util.constant
import kotlinx.coroutines.flow.flow
/**
* @description : uploaddatabasemanager
*/
class uploaddatabasemanager(private val context: context) {
//每个用户最大存储上传记录个数
private val record_limit_count=1000
private val database: uploaddatabase by lazy {
uploaddatabase.getinstance(context)
}
private val dao: uploadrecorddao by lazy {
database.uploadrecorddao()
}
/**
* 新增记录
* 每个用户id最多1000条数据,超过的要删除掉
*/
fun insertuploadrecord(record: localuploadrecord): long {
val id=dao.insert(record)
val count=dao.getrecordcountbyuser(record.userid)
if (count>record_limit_count){
// 删除超过1000条的最老记录
val deletecount=count-record_limit_count
if(deletecount>0){
dao.deleteoldest(record.userid,deletecount)
klog.d(constant.tag,"insertuploadrecord deleteoldest,sumsize:$count, deletecount:$deletecount")
}
}
return id
}
//更新上传记录
fun updateuploadrecord(record: localuploadrecord) {
dao.update(record)
}
// 获取用户的所有上传记录(flow版本,用于观察数据变化)
fun getuploadrecordsbyuser(userid: string): flow<list<localuploadrecord>> {
return dao.getrecordsbyuser(userid)
}
// 根据userid和filestatus获取记录
fun getuploadrecordsbyuser(userid: string,statuslist: list<filestatus>): list<localuploadrecord>{
return dao.getrecordsbyuser(userid,statuslist)
}
// 分页获取用户的上传记录
suspend fun getuploadrecordspaged(
userid: string,
page: int,
pagesize: int = 20
): pagedresult<localuploadrecord> {
val offset = (page - 1) * pagesize
val records = dao.getrecordsbyuserpaged(userid, pagesize, offset)
val totalcount = dao.getrecordcountbyuser(userid)
val totalpages = (totalcount + pagesize - 1) / pagesize
return pagedresult(
data = records,
currentpage = page,
pagesize = pagesize,
totalcount = totalcount,
totalpages = totalpages
)
}
// 根据id获取记录
fun getrecordbyid(id: long): localuploadrecord? {
return dao.getrecordbyid(id)
}
}3.5 使用数据库
//在activity或viewmoudle中使用数据库
private val roommanager: uploaddatabasemanager by lazy {
uploaddatabasemanager(vcapplication.getinstance())
}
//查询数据库数据,使用时应该在线程中调用,数据库操作属于耗时操作
viewmodelscope.launch(dispatchers.io) {
val filelist=roommanager.getuploadrecordsbyuser(userid)
}这里重点说一下,flow中的很好用,可以看下博主示例dao中这里的flow<list<localuploadrecord>>,这样子定义后,如果数据库有更新,会自动收到通知,不用自己主动查询。
到此这篇关于android room数据库的基本使用的文章就介绍到这了,更多相关android room使用内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论