Jetpack
已经好久了,之前一直断断续续的使用过一些,但是都没有整理过.学习就要记笔记或者在项目中实践,不然很容易时间长的话忘记AndroidX
升级新版本遇到的5.1
和5.0
的系统WebView必崩的问题,我建议使用exclude
同意一下AdnroidX
的版本apply plugin: 'kotlin-kapt'
dependencies {
def room_version = "2.2.3"
implementation "androidx.room:room-runtime:$room_version"
annotationProcessor "androidx.room:room-compiler:$room_version" // For Kotlin use kapt instead of annotationProcessor
// optional - Kotlin Extensions and Coroutines support for Room
implementation "androidx.room:room-ktx:$room_version"
// optional - RxJava support for Room
implementation "androidx.room:room-rxjava2:$room_version"
// optional - Guava support for Room, including Optional and ListenableFuture
implementation "androidx.room:room-guava:$room_version"
// Test helpers
testImplementation "androidx.room:room-testing:$room_version"
}
@PrimaryKey
表示主键,autoGenerate
属性表示是否自增@ColumnInfo
表示指定列名@Ignore
表示忽略此字段,表中就没有此字段@Entity(tableName = "user")
data class User(
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = "id")
val id: Long,
@ColumnInfo(name = "name")
var name: String?,
@ColumnInfo(name = "address")
var address: String?,
@Ignore
var birthday: String?
)
@Dao
interface UserDao {
/**
* 查询所有用户
*/
@Query("SELECT * FROM user")
fun getAll(): List
/**
* 根据id查询到某一个用户
*/
@Query("SELECT * FROM user WHERE id=(:uid) ")
fun loadAllById(uid: Int): User
/**
* 根据用户id数组查询到一批用户
*/
@Query("select * from user where id in (:ids)")
fun loadAllByIds(ids: IntArray): List
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insertUser(user: User?)
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insertUser(users: List)
@Insert
fun deleteUser(user: User?)
//只返回name的子集
@Query("SELECT name From user")
fun loadFullName(): List
}
data class NameTuple(
@ColumnInfo(name = "name") var name: String?
)
操作数据库请在子线程操作,UI线程刷新,
当然Room也支持在主线程操作,不过不建议,如果需要声明在主线程操作,记得声明
fallbackToDestructiveMigration()
属性
@Database(entities = [User::class], version = 1)
abstract class UserDataBase : RoomDatabase() {
companion object {
@Volatile
private var INSTANCE: UserDataBase? = null
fun getInstance(context: Context): UserDataBase =
INSTANCE ?: synchronized(this) {
INSTANCE ?: (
Room.databaseBuilder(
context.applicationContext,
UserDataBase::class.java,
"user_database.db"
).allowMainThreadQueries()
.fallbackToDestructiveMigration()
.build()
).also {
INSTANCE = it
}
}
}
abstract fun userDao(): UserDao
}
插入一条数据
OnConflictStrategy.REPLACE
表示插入的时候有该数据的情况下会直接替换
interface UserDao{
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insertUser(user: User?)
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insertUser(users: List)
}
UserDataBase.getInstance(this).userDao().insertUser(User(1, "小明", "北京朝阳区"))
UserDataBase.getInstance(this).userDao().insertUser(User(2, "小红", "北京通州区"))
id | name | address |
---|---|---|
1 | 小明 | 北京朝阳区 |
2 | 小红 | 北京通州区 |
val userList = arrayListOf(User(3, "小张", "北京丰台区"),User(4, "小王", "北京海淀区"))
UserDataBase.getInstance(this).userDao().insertUser(userList)
id | name | address |
---|---|---|
1 | 小明 | 北京朝阳区 |
2 | 小红 | 北京通州区 |
3 | 小张 | 北京丰台区 |
4 | 小王 | 北京海淀区 |
sql
语句做一些条件查询,下面是一些基本的简单查找interface UserDao{
@Query("SELECT * FROM user")
fun getAll(): List
/**
* 根据id查询到某一个用户
*/
@Query("SELECT * FROM user WHERE id = (:uid) ")
fun loadAllById(uid: Int): User
/**
* 根据用户id数组查询到一批用户
*/
@Query("select * from user where id in (:ids)")
fun loadAllByIds(ids: IntArray): List
/**
* 查询到的用户只返回user表中的name列信息
*/
@Query("SELECT name From user")
fun loadFullName(): List
}
UserDataBase.getInstance(this).userDao().getAll()
UserDataBase.getInstance(this).userDao().loadAllById(1)
UserDataBase.getInstance(this).userDao().loadAllByIds(intArrayOf(1,2))
UserDataBase.getInstance(this).userDao().deleteUser(User(1, "小明", "北京朝阳区"))
//同样也可以传入list批量删除
UserDataBase.getInstance(this).userDao().updateUser(User(2, "小小红", "上海"))
Database
中version+1
@Database(entities = [User::class], version = 2)
abstract class UserDataBase : RoomDatabase() {}
也可以直接在构建DataBase
类的时候声明fallbackToDestructiveMigration()
属性,不过这样升级会导致之前的数据情况
version增加的同事,提供Migration,这样会保证数据的正常,记得在对应Entity
也增加对应的属性
Migration也支持直接从version1->version4,不过我感觉还是一步一步升级比较符合,避免未知错误
fun getInstance(context: Context): UserDataBase =
INSTANCE ?: synchronized(this) {
INSTANCE ?: (
Room.databaseBuilder(
context.applicationContext,
UserDataBase::class.java,
"user_database.db"
).allowMainThreadQueries()
.addMigrations(migration)
.build()
).also {
INSTANCE = it
}
}
private val migration = object : Migration(1, 2) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL(
"ALTER TABLE user "
+ " ADD COLUMN age INTEGER"
)
}
}