注册

Kotlin实战---使用Room封装本地数据层

没有Kotlin基础的小伙伴先进这里→
Koltin基础文章


Kotlin网络模型的实现→
Kotlin网络模型的实现


kotlin实战---MVP模式实现登录,实现Base层封装→
kotlin实战---MVP模式实现登录,实现Base层封装


1、为什么使用Room


Room 是一个 SQLite 对象映射库。它可用来避免样板代码,还可以轻松地将 SQLite 表数据转换为 Java 对象。Room 提供 SQLite 语句的编译时检查,并且可以返回 RxJava、Flowable 和 LiveData 可观察对象,使用ROOM可以让你更简单,更流畅的操作数据库,使用简单通过注解的方式就能对数据库进行增删改查,Google工程师帮你封装了访问SqlLite的代码,使你的代码性能更高


2、数据库的封装


先来一个图,理清思路再看代码


在这里插入图片描述


2.1、LocalRoomRequestManager


接口层实现,类似于网络模块里的API,将操作SqlLite的接口写到这里边


/***
* 数据库获取标准接口,数据库读取
* 只为 LocalRoomRequestManager 服务
* DB 数据
*/
interface IDatabaseRequest {
fun insertStudents(vararg students: Student)

fun updateStudents(vararg students: Student)

fun deleteStudents(vararg students: Student)

fun deleteAllStudent()

fun queryAllStudent() : List<Student> ?

// TODO 可扩展 ...
}

/**
* 为了扩展,这样写(在仓库里面的)
* 本地获取标准接口(在仓库里面) 也就是本地的数据读取(包括本地xml数据,等)
* 只为 LocalRoomRequestManager 服务
*
* xml 数据 本地数据
*/
interface ILocalRequest {
}
复制代码

LocalRoomRequestManager类的实现,初始化的通过dataBase层获取dao,然后通过dao层进行增删改查


class LocalRoomRequestManager :ILocalRequest,IDatabaseRequest{
var studentDao:StudentDao?=null
//相当于Java代码的构造代码块
init{
val studentDatabase=StudentDatabase.getDataBase()
studentDao=studentDatabase?.getStudentDao()
}
companion object{
var INSTANCE: LocalRoomRequestManager? = null

fun getInstance() : LocalRoomRequestManager {
if (INSTANCE == null) {
synchronized(LocalRoomRequestManager::class) {
if (INSTANCE == null) {
INSTANCE = LocalRoomRequestManager()
}
}
}
return INSTANCE!!
}
}
override fun updateStudents(vararg students: Student) {
studentDao?.updateStudents(*students)
}

override fun deleteStudents(vararg students: Student) {
studentDao?.deleteStudent(*students)
}

override fun deleteAllStudent() {
studentDao?.deleteAllStudent()
}

override fun queryAllStudent(): List<Student>? {
return studentDao?.queryAllStudents()
}

override fun insertStudents(vararg students: Student) {
studentDao?.insertStudents(*students)
}

}
复制代码

2.2、Room操作


真正用来操作数据库的代码


初始化数据库


@Database(entities = [Student::class],version = 1)
abstract class StudentDatabase: RoomDatabase() {
abstract fun getStudentDao():StudentDao

companion object{
private var INSTANCE:StudentDatabase?=null
//Application 调用
fun getDatabase(context: Context):StudentDatabase?{
if(INSTANCE==null){
INSTANCE=Room.databaseBuilder(context,StudentDatabase::class.java,"student_database.db")
.allowMainThreadQueries()//允许在主线程查询
.build()
}
return INSTANCE
}
//使用者调用
fun getDataBase():StudentDatabase?= INSTANCE
}

}
复制代码

在Application里去初始化database


class MyApplication : Application() {

override fun onCreate() {
super.onCreate()

// 初始化
StudentDatabase.getDatabase(this)
}

}
复制代码

Room.databaseBuilde 就是实例化的DataBase的实现类
实现类里的代码:
在这里插入图片描述
这些都是框架生成的代码,省去了我们许多的样板代码
Dao层和Entity实现


@Dao
interface StudentDao {
/***
* 可变参数,插入数据
*/
@Insert
fun insertStudents(vararg students:Student)
//更新数据
@Update
fun updateStudents(vararg students:Student)

//根据条件删除
@Delete
fun deleteStudent(vararg students:Student)
//删除全部
@Query("delete from student")
fun deleteAllStudent()
//查询全部
@Query("SELECT * FROM student ORDER BY ID DESC")
fun queryAllStudents():List<Student>

}

@Entity
class Student(){
@PrimaryKey(autoGenerate = true)//设置为主键,自动增长
var id:Int=0
@ColumnInfo(name="name")//别名 数据库中的名字如果不设置,默认是属性名称
lateinit var name:String
@ColumnInfo(name ="phoneNumber")
lateinit var phoneNumber:String
//次构造
constructor(name:String,phoneNumber:String): this(){
this.name=name
this.phoneNumber=phoneNumber
}
}
复制代码

框架生成的代码,大家可以自己去看一下,里面自动添加了事务,也加了锁,非常的nice
写完这些再去用MVP把LocalRoomRequestManager和Model层连起来,MVP上一篇贴的很详细了,这次的就不贴了
Kotlin版的适配器写法


class CollectAdapter :RecyclerView.Adapter<CollectAdapter.MyViewHolder>() {
// 接收 数据库的数据
var allStudents: List<Student> = ArrayList()
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
val layoutInflater: LayoutInflater = LayoutInflater.from(parent.context)
val itemView: View = layoutInflater.inflate(R.layout.item_collect_list, parent, false)
return MyViewHolder(itemView)
}

override fun getItemCount(): Int =allStudents.size

override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
val student: Student = allStudents[position]
holder.tvID.text = "${position + 1}"
holder.tvName.text = student.name
holder.tvPhoneNumber.text = "${student.phoneNumber}"
}

inner class MyViewHolder(itemView: View):RecyclerView.ViewHolder(itemView){
var tvID: TextView = itemView.findViewById(R.id.tv_id)
var tvName: TextView = itemView.findViewById(R.id.tv_name)
var tvPhoneNumber: TextView = itemView.findViewById(R.id.tv_phoneNumber)
}

}
复制代码

最终的效果


在这里插入图片描述


3、总结


需要注意的点在可变参数的传递过程中,不能将参数直接丢给方法得加一个*
LocalRoomRequestManager.getInstance().insertStudents(*students)
体验用Kotlin开发项目的感觉,感觉比Java好用很多,还是很nice的,作为官方直推的语言还是挺值得学习的,


作者:被遗忘的凉白开
链接:https://juejin.cn/post/6955767367192281124
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

0 个评论

要回复文章请先登录注册