Android Component Room Database 实践过程 - A

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 getAll();

    @Query("SELECT * FROM user WHERE uid IN (:userIds)")
    List 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 ,看官网

Android Component Room Database 实践过程 - A_第1张图片
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();

src //非常粗糙的代码

github

你可能感兴趣的:(Android,android,components,room)