Android Component Room Database 实践过程 - A
参考文档 //可以直接去看文档学习。
Adding Components to your Project
Room Persistence Library
内容
1 Room概况
2 Sample代码
3 问题记录
4 src
Room 三个部分
Database
Entity
DAO
project build.gradle
allprojects {
repositories {
jcenter()
//for room
maven { url 'https://maven.google.com' }
}
}
app module build.gradle
android {
// ...
defaultConfig {
// ...
//for room scehma
javaCompileOptions {
annotationProcessorOptions {
arguments = ["room.schemaLocation": "$projectDir/schemas".toString()]
}
}
// ...
}
// ...
}
dependencies {
// ...
//room
compile "android.arch.persistence.room:runtime:1.0.0-alpha5"
annotationProcessor "android.arch.persistence.room:compiler:1.0.0-alpha5"
// ...
}
Entity //代码是官网的, 注意自己加上 getter & setter,否则报错
@Entity
public class User {
@PrimaryKey
private int uid;
@ColumnInfo(name = "first_name")
private String firstName;
@ColumnInfo(name = "last_name")
private String lastName;
// Getters and setters are ignored for brevity,
// but they're required for Room to work.
}
Dao //官网 这个非常方便了。 后续加上 Rxjava2 感觉会更好
/**
* @Author : Administrator
* @Date : 2017/8/2 10:22
* @Version:
*/
@Dao
public interface UserDao {
@Query("SELECT * FROM user")
List<User> getAll();
@Query("SELECT * FROM user WHERE uid IN (:userIds)")
List<User> loadAllByIds(int[] userIds);
@Query("SELECT * FROM user WHERE first_name LIKE :first AND "
+ "last_name LIKE :last LIMIT 1")
User findByName(String first, String last);
@Insert
void insertAll(User... users);
@Insert
void insertA(User user);
@Query("SELECT * FROM user")
public User[] loadAllUsers();
@Delete
void delete(User user);
}
Database // 实际中用单例模式
new Thread(new Runnable() {
@Override
public void run() {
mDb = Room.databaseBuilder(getApplicationContext(), AppDataBase.class, "database-name").build();
}
}).start();
//暂时允许在mainthread 处理
//mDb = Room.databaseBuilder(getApplicationContext(), AppDataBase.class, "database-name").allowMainThreadQueries().build();
insert 数据 //这里有个坑。。。
//不使用 transaction
User user_b = new User();
...setUser...
mDb.userDao().insertA(user);
//使用 transaction 注意啦 注意 注意
User user_a = new User();
...setUser...
mDb.beginTransaction();
mDb.userDao().insertA(user);
//事务必须用这行么???
mDb.setTransactionSuccessful();
mDb.endTransaction();
query //正常看文档
User[] users = null;
//用Dao访问。
users = mDb.userDao().loadAllUsers();
delete //正常看文档
几个问题记录一下
编译错误
解 : Entuty 加 getter & setter
Schema 错误提示
Warning: //此时build是成功的。
Error:(13, 17) 警告: Schema export directory is not provided to the annotation processor so we cannot export the schema. You can either provide `room.schemaLocation` annotation processor argument OR set exportSchema to false.
解 [ref]https://stackoverflow.com/questions/44322178/room-schema-export-directory-is-not-provided-to-the-annotation-processor-so-we
//官网文档也有写的。
方案A exportSachma = false;
@Database(entities = { YourEntity.class }, version = 1, exportSchema = false)
public abstract class AppDatabase extends RoomDatabase {
...
}
方案B //看看大神的回答, 不说答案正确与否, 就这种代码注释值得学习。
android {
// ... (compileSdkVersion, buildToolsVersion, etc)
defaultConfig {
// ... (applicationId, miSdkVersion, etc)
javaCompileOptions {
annotationProcessorOptions {
arguments = ["room.schemaLocation": "$projectDir/schemas".toString()]
}
}
}
// ... (buildTypes, compileOptions, etc)
}
生成的Schema //关于Schema ,看官网
Schema JSON
{
"formatVersion": 1,
"database": {
"version": 1,
"identityHash": "559f8304933f593d9feffa68b452449b",
"entities": [
{
"tableName": "User",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`uid` INTEGER, `first_name` TEXT, `last_name` TEXT, PRIMARY KEY(`uid`))",
"fields": [
{
"fieldPath": "uid",
"columnName": "uid",
"affinity": "INTEGER"
},
{
"fieldPath": "firstName",
"columnName": "first_name",
"affinity": "TEXT"
},
{
"fieldPath": "lastName",
"columnName": "last_name",
"affinity": "TEXT"
}
],
"primaryKey": {
"columnNames": [
"uid"
],
"autoGenerate": false
},
"indices": [],
"foreignKeys": []
}
],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, \"559f8304933f593d9feffa68b452449b\")"
]
}
}
/data/data/databases 目录下没有数据库文件
解 : 此时还没有数据 insert ,所以没出来。 insert后会出现。
Debugging 模式卡住
解: 此时删除schema 文件就能正常Debugging //不知到原因。
数据写入不了 //看前边的代码 – 感谢 monroe ,北京-秦微明 @Android studio QQ 群 的提点。
解 : 因为 transaction 完成需要commit,标记事务成功 setTransactionSuccessful()
//这代码不能正常 insert why?
mDb.beginTransaction();
mDb.userDao().insertA(user);
mDb.endTransaction();