最近在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)