Kotlin中使用Room数据库

最近在kotlin环境下,写了一个room数据库的demo,各种情况跑了一下,在此总结一下。

涉及情况:增、删、改、查、排序

1、环境搭建
1.1、Android Studio下,新建一个kotlin项目,
1.2、去app的build.gradle中进行一些配置
顶部增加

apply plugin: 'kotlin-kapt'

然后

defaultConfig {

javaCompileOptions {
annotationProcessorOptions {
arguments = [“room.schemaLocation”:
“$projectDir/schemas”.toString()]
}
}
}

1.3、导入依赖

implementation ‘android.arch.persistence.room:runtime:1.1.1’ kapt
‘android.arch.persistence.room:compiler:1.1.1’

2、创建一个Application,用于提供全局上下文

class MyApplication : Application() {

companion object {

    var instance: MyApplication by Delegates.notNull()

    fun instance() = instance
}

override fun onCreate() {
    super.onCreate()

    instance = this
}

}

3、分别创建Student和Teacher(我写了2张表)

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

@Entity(tableName = “Student”) data class Student(

@PrimaryKey(autoGenerate = true)
var studentID: Int?,
@ColumnInfo(name = "s_name")
var studentName: String?,
@ColumnInfo(name = "s_type")
var studentType: String?

)

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

@Entity(tableName = “Teacher”) data class Teacher(

@PrimaryKey(autoGenerate = true)
var teacherID: Int?,
@ColumnInfo(name = "t_name")
var teacherName: String?,
//教学年限
@ColumnInfo(name = "t_year")
var teachYear: Int?

)

4、与之对应的,分别创建StudentDao和TeacherDao

import android.arch.persistence.room.*

@Dao interface BaseDao {

@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insertAll(list: MutableList<T>)

@Delete
fun delete(element: T)

@Delete
fun deleteList(elements:MutableList<T>)

@Delete
fun deleteSome(vararg elements:T)

@Update
fun update(element: T)

}
import android.arch.persistence.room.*

@Dao interface StudentDao:BaseDao {

@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insert(element:Student)

@Query("select * from Student")
fun getAllStudents():MutableList<Student>

@Query("select * from Student where studentID = :studentID")
fun getStudnet(studentID:Int):Student

@Query("select * from Student order by studentID desc ")
fun getAllByDateDesc():MutableList<Student>

@Query("delete from Student")
fun deleteAll()

}

import android.arch.persistence.room.*

@Dao interface TeacherDao:BaseDao {

@Insert
fun insert(element:Teacher)

@Query("select * from Teacher")
fun getAllTeachers():MutableList<Teacher>

@Query("select * from Teacher where teacherID = :teacherID")
fun getTeacher(teacherID:Int):Teacher

@Query("select * from Teacher order by t_year desc ")
fun getAllByDateDesc():MutableList<Teacher>

@Query("delete from Teacher")
fun deleteAll()

}

这里,注意下StudentDao和TeacherDao中,insert上面的注解,有区别,后面会说到

5、接下来,创建AppDataBase

import android.arch.persistence.room.Database import
android.arch.persistence.room.RoomDatabase import
android.arch.persistence.room.Room

@Database(entities = [Student::class, Teacher::class], version = 1)
abstract class AppDataBase : RoomDatabase() {

abstract fun getStudentDao(): StudentDao

abstract fun getTeacherDao(): TeacherDao

companion object {

    val instance = Single.sin

}

private object Single {

    val sin :AppDataBase= Room.databaseBuilder(
        MyApplication.instance(),
        AppDataBase::class.java,
        "User.db"
    )
        .allowMainThreadQueries()
        .build()
}

}

这里,我用的是 静态内部类 的单例,还可以写作

import android.arch.persistence.room.Database import
android.arch.persistence.room.RoomDatabase import
android.arch.persistence.room.Room

@Database(entities = [Student::class, Teacher::class], version = 1)
abstract class AppDataBase : RoomDatabase() {

abstract fun getStudentDao(): StudentDao

abstract fun getTeacherDao(): TeacherDao

companion object {

    @Volatile
    private var instance: AppDataBase? = null

    fun getDBInstace(): AppDataBase {

        if (instance == null) {

            synchronized(AppDataBase::class) {

                if (instance == null) {

                    instance = Room.databaseBuilder(
                        MyApplication.instance(),
                        AppDataBase::class.java,
                        "User.db"
                    )
                        .allowMainThreadQueries()
                        .build()
                }
            }
        }
        return instance!!
    }

}

}

这里,不做讨论,kotlin的单例,也有多种写法。

到此为止,准备工作,都做完了。开始实际的使用:
Activity中:

val sDao: StudentDao = AppDataBase.instance.getStudentDao()

var s_1 = Student(1, “s1”, “小学”)
var s_2 = Student(2, “s2”, “小学”)
var s_3 = Student(3, “s3”, “小学”)
var s_4 = Student(4, “s4”, “大学”)
var s_5 = Student(5, “s5”, “大学”)
var s_6 = Student(6, “s6”, “大学”)

var sList: MutableList = mutableListOf()

sList.add(s_1) sList.add(s_2) sList.add(s_3) sList.add(s_6)
sList.add(s_5) sList.add(s_4)

//可以直接把list传进去,也可以一个一个单独添加 sDao.insertAll(sList)

var sList_select_1: MutableList = sDao.getAllStudents()

for (i in sList_select_1.indices) { println(sList_select_1.get(i)) }

日志: Student(studentID=1, studentName=s1, studentType=小学)
Student(studentID=2, studentName=s2, studentType=小学)
Student(studentID=3, studentName=s3, studentType=小学)
Student(studentID=4, studentName=s4, studentType=大学)
Student(studentID=5, studentName=s5, studentType=大学)
Student(studentID=6, studentName=s6, studentType=大学)

插入,查询成功,接下来,对数据进行修改:

//注意,这里我用的是insert,而不是 update

sDao.insert(Student(1, “s1”, “大学”))

var sList_select_2: MutableList<Student> = sDao.getAllStudents()

for (i in sList_select_2.indices) {
	println(sList_select_2.get(i))
}

日志:
Student(studentID=1, studentName=s1, studentType=大学)//这条数据变了
Student(studentID=2, studentName=s2, studentType=小学)
Student(studentID=3, studentName=s3, studentType=小学)
Student(studentID=4, studentName=s4, studentType=大学)
Student(studentID=5, studentName=s5, studentType=大学)
Student(studentID=6, studentName=s6, studentType=大学)

接下来,对数据进行删除试试

sDao.deleteSome(Student(100, “s100”, “高中”), s_6) var sList_select_3:
MutableList = sDao.getAllStudents()

for (i in sList_select_3.indices) { println(sList_select_3.get(i)) }

日志: Student(studentID = 1, studentName = s1, studentType = 大学)
Student(studentID = 2, studentName = s2, studentType = 小学)
Student(studentID = 3, studentName = s3, studentType = 小学)
Student(studentID = 4, studentName = s4, studentType = 大学)
Student(studentID = 5, studentName = s5, studentType = 大学)

从删除可以看出,删除不存在的Student数据,不会报错,只是没有效果,删除存在的数据,就是正常删除

接下来,对Teacher表进行一些操作

val tDao: TeacherDao = AppDataBase.instance.getTeacherDao()

var t_1 = Teacher(1, “t1”, 10) var t_2 = Teacher(2, “t2”, 5) var t_3 =
Teacher(3, “t3”, 3) var t_4 = Teacher(4, “t4”, 14) var t_5 =
Teacher(5, “t5”, 22)

var tList: MutableList = mutableListOf()
tList.add(t_1) tList.add(t_2) tList.add(t_3) tList.add(t_4)
tList.add(t_5)

tDao.insertAll(tList)

var tList_select_1: MutableList = tDao.getAllTeachers()

for (i in tList_select_1.indices) { println(tList_select_1.get(i)) }

日志: Teacher(teacherID=1, teacherName=t1, teachYear=10)
Teacher(teacherID=2, teacherName=t2, teachYear=5) Teacher(teacherID=3,
teacherName=t3, teachYear=3) Teacher(teacherID=4, teacherName=t4,
teachYear=14) Teacher(teacherID=5, teacherName=t5, teachYear=22)

对教师数据进行排序(按照教学年限)

var tList_select_2: MutableList = tDao.getAllByDateDesc()

for (i in tList_select_2.indices) { println(tList_select_2.get(i)) }

日志: Teacher(teacherID=5, teacherName=t5, teachYear=22)
Teacher(teacherID=4, teacherName=t4, teachYear=14)
Teacher(teacherID=1, teacherName=t1, teachYear=10)
Teacher(teacherID=2, teacherName=t2, teachYear=5) Teacher(teacherID=3,
teacherName=t3, teachYear=3)

现在,要对 ID=1 的老师做修改,把他的教学年限,改成11,还是用之前Student的那种写法:

tDao.insert(Teacher(1,“t1”,11))

报错: Caused by: android.database.sqlite.SQLiteConstraintException:
UNIQUE constraint failed: Teacher.teacherID (Sqlite code 1555
SQLITE_CONSTRAINT_PRIMARYKEY), (OS error - 2:No such file or
directory)

到这来,应该知道,insert上面那句注解

@Insert(onConflict = OnConflictStrategy.REPLACE)

的含义和作用了吧!

如果没有这个注解,插入已有数据,会报错!如果有这个注解,插入以后数据,仅仅是替换。

因为Teacher没有加这个注解,用update试试

tDao.update(Teacher(1, “t1”, 11))

var tList_select_3: MutableList = tDao.getAllTeachers()

for (i in tList_select_3.indices) { println(tList_select_3.get(i)) }

日志: Teacher(teacherID=1, teacherName=t1, teachYear=11)
Teacher(teacherID=2, teacherName=t2, teachYear=5) Teacher(teacherID=3,
teacherName=t3, teachYear=3) Teacher(teacherID=4, teacherName=t4,
teachYear=14) Teacher(teacherID=5, teacherName=t5, teachYear=22)

总结

添加依赖 --> 创建数据库(AppDataBase) --> 定义实体表 (@Entity Student/Teacher) --> Dao类(StudentDao和TeacherDao)

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Kotlin使用Room数据库是一种常见的做法,Room是Google官方提供的一个SQLite对象映射库,用于简化与SQLite数据库的交互。以下是使用Room数据库的几个步骤: 1. 添加依赖:在项目的`build.gradle`文件添加以下依赖: ```kotlin implementation "androidx.room:room-runtime:2.4.0" kapt "androidx.room:room-compiler:2.4.0" ``` 2. 创建实体类:创建一个Kotlin类来表示数据库的表,并使用`@Entity`注解标记它。例如,如果我们要创建一个名为`User`的表,可以这样写: ```kotlin @Entity(tableName = "users") data class User( @PrimaryKey val id: Int, val name: String, val age: Int ) ``` 3. 创建DAO接口:创建一个Kotlin接口来定义访问数据库的操作,并使用`@Dao`注解标记它。例如,如果我们要创建一个名为`UserDao`的接口,可以这样写: ```kotlin @Dao interface UserDao { @Query("SELECT * FROM users") fun getAll(): List<User> @Insert fun insertAll(vararg users: User) @Delete fun delete(user: User) } ``` 4. 创建数据库:创建一个继承自`RoomDatabase`的抽象类,并在其定义数据库的实例和DAO接口的访问方法。例如,如果我们要创建一个名为`AppDatabase`的数据库类,可以这样写: ```kotlin @Database(entities = [User::class], version = 1) abstract class AppDatabase : RoomDatabase() { abstract fun userDao(): UserDao } ``` 5. 初始化数据库:在应用程序的入口处(通常是`Application`类的`onCreate()`方法),使用`Room.databaseBuilder`方法来创建数据库的实例。例如: ```kotlin val db = Room.databaseBuilder( applicationContext, AppDatabase::class.java, "database-name" ).build() ``` 6. 使用数据库:通过调用DAO接口定义的方法,可以进行数据库的增删改查操作。例如: ```kotlin val userDao = db.userDao() val allUsers = userDao.getAll() userDao.insertAll(User(1, "John Doe", 25)) val user = userDao.getAll().first() userDao.delete(user) ``` 这些是使用KotlinRoom数据库的基本步骤,希望对你有所帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值