1、gradle配置
//google room数据库
implementation 'android.arch.persistence.room:runtime:1.0.0'
annotationProcessor 'android.arch.persistence.room:compiler:1.0.0'
//rxAndroid && rxJava1
implementation 'io.reactivex:rxandroid:1.2.1'
implementation 'io.reactivex:rxjava:1.3.2'
注意数据库相关文件请在混淆文件中保持。
2、database/model/dao是互相关联的
一个基本的room数据库应该包括:数据库、数据模型和dao三个部分。
AppDatabase:
@Database(entities = {Message.class}, version = 1, exportSchema = false)
public abstract class AppDatabase extends RoomDatabase {
private static final String DB_NAME = "AppDatabase.db";
public static final String TABLE_MESSAGE = "message";
private static volatile AppDatabase instance;
public static AppDatabase getInstance(Context context) {
if (instance == null) {
synchronized (AppDatabase.class) {
if (instance == null) {
instance = create(context.getApplicationContext());
}
}
}
return instance;
}
private static AppDatabase create(final Context context) {
// context必须为ApplicationContext
// inMemoryDatabaseBuilder:可以创建一个内存数据库。这样就避免了每次测试之后都需要清理数据。
// 内存数据库每次测试后,我们还必须保证都关闭了数据库连接。(database.close();)
// return Room.inMemoryDatabaseBuilder(
// context,
// ZJSDatabase.class).build();
return Room.databaseBuilder(
context,
AppDatabase.class,
DB_NAME).build();
}
public abstract MessageDao getMessageDao();
}
@Database注解表示这是一个数据库。
entities = {Message.class}定义数据模型,里边是一个数组,所有数据模型都要写进去。
version = 1是数据库版本号,升级数据库的时候需要用到。
AppDatabase应该是一个单例,这个不难理解。
两种databaseBuilder:(1)inMemoryDatabaseBuilder是一个内存数据库,数据只在内存中,一般调试用,不需要每次都进设置清理数据,很方便;(2)databaseBuilder,正常理解的数据库,正式测试和发布的时候用。
Model:
@Entity(tableName = TABLE_MESSAGE)
data class Message(
@ColumnInfo(name = "my_content") var content: String = "",
var title: String = "",
var news_id: String = "",
var news_type: Int = 0,
var cover_img_url: String? = "",
var push_time: Long = 0) {
@PrimaryKey(autoGenerate = true)
var id: Int = 0
@Ignore
var isSelected = false
}
注意model一定要有默认构造器,否则会报错。
@Entity(tableName = TABLE_MESSAGE)定义数据模型的一些基本信息,比如表名称
@ColumnInfo(name = "my_content") 可以自定义列信息,比如列名称
@PrimaryKey(autoGenerate = true)主键标志,可以设置是否自增
@Ignore 忽略该属性,即该属性不会被写入数据库中
Dao:
@Dao
interface MessageDao {
@Query("SELECT * FROM message ORDER BY push_time DESC")
abstract fun loadAllMessages(): List
@Insert(onConflict = IGNORE)
abstract fun insertMessage(message: Message)
@Query("SELECT COUNT(1) FROM message")
abstract fun getMessageCont(): Int
@Delete
abstract fun deleteMessages(vararg message: Message)
@Query("DELETE FROM message")
abstract fun deleteAllMessages()
}
dao接口主要就是定义sql方法的。可以使用标准的sql语句。也可以使用Room提供的一些注解。但是要注意,用传统sql时注解请使用@Query。
比如delete,你可以使用sql来写:
@Query("DELETE FROM message where id = (:id)")
abstract fun deleteMessageById(id: Int)
也可以用Room提供的delete方法:
@Delete
abstract fun deleteMessage(message: Message)
3、数据写入/读取
Dao定义好了之后,写入/读取其实操作差不多,只以读取为例。注意数据库操作必须在子线程中。
Observable
.create(Observable.OnSubscribe> {
val allMessages = AppDatabase.getInstance(this).messageDao.loadAllMessages()
it.onNext(allMessages)
it.onCompleted()
})
.doOnError {
}
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({
})