一、定义
- 轻量级orm数据库,本质上是一个SQLite抽象层,使用更加简单(类似于Retrofit)
- 编译时注解:开发阶段可以通过注解的方式标记相关功能,编译时自动生成相应的impl实体类
- 提供丰富的编译时校验,以及错误提示
二、用法
1.sqlite数据库
使用:
const val TABLE_NAME = "table_user"
const val COLUMN_NAME_KEY = "cache_user"
const val COLUMN_NAME_DATA = "cache_user"
private const val SQL_CREATE_TABLE_USER =
"CREATE TABLE $TABLE_NAME (" +
"$ID INTEGER PRIMARY KEY,"+
"$COLUMN_NAME_TITLE TEXT,"+
"$COLUMN_NAME_SUBTITLE TEXT)"
class CacheDbHelper(context: Context):SQLiteOpenHelper(context,DATABASE_NAME,null,){
companion object {
const val DATABASE_VERSION = 1
const val DATABASE_NAME ="cache.db"
}
override fun onCreate(db: SQLiteDatabase?) {
db.execSQL(SQL_CREATE_TABLE_USER)
}
override fun onUpgrade(db: SQLiteDatabase?, oldVersion: Int, newVersion: Int) {
//根据oldVersion和newVersion编写相应的SQL语句对数据库进行升级
//在实际应用中,这是比较难处理的一部分,因为缺少必要的验证,极容易出错
}
//基类中包含了两个重要的方法 getWritableDatabase()和 getReadableDatabase() 操作数据库的入口
}
缺点:
- SQL语句的正确性及安全性都没有保证,问题需要运行后才发现
- 很容易在主线程对数据库进行操作
- 从数据库数据到使用的类数据之间的转换繁琐
2.Room数据库
添加依赖
api "android.arch.persistence.room:runtime:2.2.0"
kapt "android.arch.persistence.room:compiler:2.2.0"
创建Room数据库
- @Entity:表示数据库中的表
- @DAO:数据操作对象
- @Database:数据库。必须是扩展 RoomDatabase 的抽象类。在注解中添加与数据库关联的数据表。包含使用 @Dao 注解标记的的类的抽象方法
1.定义数据表 Entity
// 1.定义 数据表
@Entity(tableName = "table_cache")
class Cache {
//@PrimaryKey 主键 autoGenerate 是否交给room来维护,自动增长
@PrimaryKey(autoGenerate = false)
@NonNull
@ColumnInfo("cache_key")
var key: String = ""
//@ColumnInfo 给字段重新命名
@ColumnInfo("cache_data")
var data: String? = null
//defaultValue 设置默认值
@ColumnInfo(name = "cacheId", defaultValue = "1")
var cache_id: Long = 0
//@Ignore 不需要在数据库中创建字段
@Ignore
var bitmap: Bitmap?= null
//@Embedded 可以让内嵌对象中的字段映射成数据库表的字段,
//要求内嵌对象(User)必须要@Entity注解标记,并且拥有一个不为空的主键
@Embedded
var user: User?= null
}
@Entity(tableName = "table user")
class User {
@PrimaryKey
@NonNull
var name: String = ""
var age = 10
}
2.定义数据库数据操作对象 Dao
//data access object 数据访问对象 ,这里面会定义数据操作的增删改查的方法
@Dao
interface CacheDao {
//查询 table_cache 表中所有的数据
@Query("select * from table_cache")
fun query1(keyword: String): List<Cache>
//查询 table_cache 表中 根据keyword匹配的第一条数据
@Query("select * from table_cache where `cache_key`=:keyword limit 1")
fun query2(keyword: String): Cache
//可以通过livedata 以观察者的形式获取数据库数据, 可以避免不必要的NPE
//可以监听数据库表中的数据值的变化,一旦发生了insert、update、delete操作。room会自动读取表中最新的数据,发送给UI层 刷新页面
@Query("select * from table_cache")
fun query3(): LiveData<List<Cache>> //rxjava observer
@Delete(entity = Cache::class)
fun delete(cache: Cache)
//
@Insert(entity = Cache::class, onConflict = OnConflictStrategy.REPLACE)
fun insert(cache: Cache)
@Update()
fun update(cache: Cache)
}
3.定义数据库,并关联上表和数据操作实体
@Database(entities = [Cache::class, User::class], version = 1, exportSchema = true)
abstract class CacheDatabase : RoomDatabase() {
abstract val cacheDao: CacheDao
companion object {
private var database: CacheDatabase? = null
@Synchronized
fun get(context: Context): CacheDatabase {
if (database == null) {
//内存数据库,也就是说这种数据库当中存储的数据,只会存留在内存当中,进程被杀死之后,数据随之丢失
// database = Room.inMemoryDatabaseBuilder(context, CacheDatabase::class.java).build()
database = Room.databaseBuilder(context, CacheDatabase::class.java, "android")
//允许在去线程操作数据库,默认是不众许。如果在主线程操作了数据库.直接报错
.allowMainThreadQueries()
//创建、打开数据库时回调
.addCallback(callback)
//指定数据查询数据时候的线程池
// .setQueryExecutor()
//用来创建supportsqliteopenhelper ,默认是:frameworksqliteopenhelperFactory
// 可以利用它自行创建supportsqliteopenhelper。来实现数据库的加密
// .openHelperFactory()
//做数据库升级 1---2
.addMigrations(migration1_2)
.build()
}
return database!!
}
val callback = object : Callback() {
override fun onCreate(db: SupportSQLiteDatabase) {
super.onCreate(db)
}
override fun onOpen(db: SupportSQLiteDatabase) {
super.onOpen(db)
}
}
val migration1_2 = object : Migration(1, 2) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("alter table table_cache add column cache_time LONG")
}
}
}
}