1.导入依赖
//room database
implementation 'androidx.room:room-runtime:2.2.3'
annotationProcessor 'androidx.room:room-compiler:2.2.3'
kapt 'androidx.room:room-compiler:2.2.3'
androidTestImplementation 'androidx.room:room-testing:2.2.3'
2.gradle设置,在在顶部添加
apply plugin: 'kotlin-kapt'
defaultConfig括号内添加
javaCompileOptions {
annotationProcessorOptions {
arguments = [
"room.schemaLocation" : "$projectDir/schemas".toString(),
"room.incremental" : "true",
"room.expandProjection": "true"]
}
}
3.新建实体类,就是建数据库表
@Entity(tableName = "worker" ,primaryKeys = arrayOf("id"))
data class Worker(
@ColumnInfo(name = "id")
var id: Long?,
@ColumnInfo(name = "name")
var name:String?
)
4.新建Dao类,就是映射数据库操作到方法中(个人理解)
@Dao
interface WorkerDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insertWorker(worker: Worker)
@Query("DELETE FROM worker WHERE name=:name")
fun deleteWorker(name: String)
@Query("SELECT * FROM worker")
fun queryAllWorkers(): List<Worker>
@Query("SELECT * FROM worker WHERE id = :id")
fun getWorkerById(id: Long): Worker
}
5.新建KotDatabase类,生成数据库
@Database(entities = [Worker::class], version = 1)
abstract class KotDatabase : RoomDatabase() {
abstract fun getWorkerDao(): WorkerDao
companion object {
@Volatile
private var INSTANCE: KotDatabase? = null
fun getInstance(context: Context): KotDatabase =
INSTANCE ?: synchronized(this) {
INSTANCE ?: buildDatabase(context).also { INSTANCE = it }
}
private fun buildDatabase(context: Context) =
Room.databaseBuilder(context.applicationContext, KotDatabase::class.java, "kot.db").allowMainThreadQueries()
.build()
}
}
这里啰嗦一句,如果不加上.allowMainThreadQueries(),你只能在子线程中操作,不能在UI主线程里操作,不然报错闪退
6.insert举例操作
Thread{
val worker = Worker(0,"李华")
KotDatabase.getInstance(applicationContext).getWorkerDao().insertWorker(worker)
val worker2 = Worker(11,"luoyanda")
KotDatabase.getInstance(applicationContext).getWorkerDao().insertWorker(worker2)
var workerM = KotDatabase.getInstance(applicationContext).getWorkerDao().getWorkerById(11);
var message:Message = Message.obtain()
message.what = 100
message.obj = workerM.name
myHandler.sendMessage(message);
}.start()
7.读写内存权限加上。
if(ContextCompat.checkSelfPermission(applicationContext,android.Manifest.permission.WRITE_EXTERNAL_STORAGE)!=PackageManager.PERMISSION_GRANTED||
ContextCompat.checkSelfPermission(applicationContext,android.Manifest.permission.READ_EXTERNAL_STORAGE)!=PackageManager.PERMISSION_GRANTED
){
ActivityCompat.requestPermissions(this@MainActivity, arrayOf(android.Manifest.permission.WRITE_EXTERNAL_STORAGE,
android.Manifest.permission.READ_EXTERNAL_STORAGE),REQ_CODE_PERMISSION)
}else{
//todo
}
。。。。
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
when(requestCode){
REQ_CODE_PERMISSION ->{
if(grantResults.size>0&&
grantResults[0]==PackageManager.PERMISSION_GRANTED&&
grantResults[1] ==PackageManager.PERMISSION_GRANTED){
//todo
}
}
}
}
8.不用data class也行,不然有自增id时无法使用,这里使用普通的class也许,构造器里不添加自增id就行,kotlin会自动曾家get/set方法的。
@Entity(tableName = "student")
class Student{
@PrimaryKey(autoGenerate = true)
var id: Long = 0 //不影响第一个元素为1,后面自增
var firstName: String? = null
var lastName: String? = null
var test:String? = null
constructor(firstName: String?, lastName: String?, test: String?) {
this.firstName = firstName
this.lastName = lastName
this.test = test
}
}
8.迁移,由于要改数据库表中的字段,比如之前没有test变量,在这里增加,保证之前的数据不会丢失。
//这里的version由1改为2,狠!狠!狠!重要,表明现在是2代数据库,如果后面再改以此为依据
@Database(entities = [Worker::class,Student::class], version = 2)
abstract class KotDatabase : RoomDatabase() {
abstract fun getWorkerDao(): WorkerDao
abstract fun getStudentDao():StudentDao
companion object {
@Volatile
private var INSTANCE: KotDatabase? = null
fun getInstance(context: Context): KotDatabase =
INSTANCE ?: synchronized(this) {
INSTANCE ?: buildDatabase(context).also { INSTANCE = it }//不空就执行方括号里的代码
}
var dd: Migration = object : Migration(1,2){ //由一代往二代迁移要做的操作
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("ALTER TABLE student ADD COLUMN test TEXT default 'test' ")
}
}
//调用迁移
private fun buildDatabase(context: Context) =
Room.databaseBuilder(context.applicationContext, KotDatabase::class.java, "kot.db").addMigrations(
dd).allowMainThreadQueries()
.build()
}
}