Android Room資料庫的使用

前言

Google終於釋出了一個和SQLite相關的庫了。之前一直都是在SQLite、XUtils、greenDao、Realm這些資料庫之間來回折騰。現在終於有一個更“正統”資料庫了。

Room是什麼?

2017 年 5 月,Google I/O ’17 發佈了 Room,至此 persistence 歸於一統 — Room。Room 具有良好的擴充性及彈性,對於多個 Table 間的複合查詢也相當的容易,簡單的標示即可產生Database、Table,對於SQL 語法頭疼的人乃一大福音。

使用Room

1、在app/build.gradle中新增以下依賴
implementation 'android.arch.persistence.room:runtime:1.1.1'
annotationProcessor 'android.arch.persistence.room:compiler:1.1.1'
2、建立JavaBean
@Entity
public class User {

    @PrimaryKey(autoGenerate = true)    //  主鍵是否自動增加,預設為false
    @ColumnInfo(name = "id")
    private int id;
    private String name;
    private int age;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
    //這裡的getter/setter方法是必須的
    //這裡的getter/setter方法是必須的
    //這裡的getter/setter方法是必須的
    //重要的事說三遍
}
這裡需要使用 @Entity 來註解該類

至少要有一個主鍵 @PrimaryKey

3、建立Dao(Data access object)

接下來,需要為我們的實體建立DAO。 DAO代表資料訪問物件,所以它是告訴我們的資料庫如何運算元據的一種方式:
@Dao
public interface UserDao {

    @Query("SELECT * FROM user")
    List getAllUsers();
    @Query("SELECT * FROM user WHERE id=:id")
    User getUser(int id);
    @Query("SELECT * FROM user")
    Cursor getUserCursor();
    @Query("SELECT * FROM user WHERE age=:age")
    List getUsersByAge(int age);
    @Query("SELECT * FROM user WHERE age=:age LIMIT :max")
    List getUsersByAge(int max, int age);

    @Insert
    void insert(User... users);
    @Insert
    void insert(User user);
    @Insert
    void insert(List userLists);

    @Update
    void update(User user);

    @Delete
    void delete(User user);
}
使用 @Dao 註解該介面

@Insert , @Update , @Delete , @Query 代表我們常用的 插入 、 更新 、 刪除 、 查詢 資料庫操作

@Insert
    @Insert
    void insert(User... users);
    @Insert
    void insert(User user);
    @Insert
    void insert(List<User> userLists);
@Query
    @Query("SELECT * FROM user")
    List<User> getAllUsers();
    @Query("SELECT * FROM user WHERE id=:id")
    User getUser(int id);
    @Query("SELECT * FROM user")
    Cursor getUserCursor();
    @Query("SELECT * FROM user WHERE age=:age")
    List<User> getUsersByAge(int age);
    @Query("SELECT * FROM user WHERE age=:age LIMIT :max")
    List<User> getUsersByAge(int max, int age);
@Update
使用 @Update 註解方法,可以使用參數實體的值更新主鍵值和參數實體的主鍵相同的行。
    @Update
    void update(User user);
@Delete
使用 @Delete 註解方法,可以刪除主鍵值和參數實體的主鍵相同的行。
    @Delete
    void delete(User user);
4、建立資料庫
@Database(entities = { User.class }, version = 1, exportSchema = false)
public abstract class UserDatabase extends RoomDatabase {

    private static final String DB_NAME = "UserDatabase.db";
    private static volatile UserDatabase instance;
    static synchronized UserDatabase getInstance(Context context) {
        if (instance == null) {
            instance = create(context);
        }

        return instance;
    }

    private static UserDatabase create(final Context context) {
        return Room.databaseBuilder(
          context,
          UserDatabase.class,
          DB_NAME
        ).build();
    }

    public abstract UserDao getUserDao();
}
這裡使用 @Database 註解該類並新增了 表名 、 資料庫版本 (每當我們改變資料庫中的內容時它都會增加),所以這裡使用 exportSchema = false

注意:除了新增表對映的類以及和資料庫版本外,還要新增 exportSchema = false 否則會報警告。

5、使用資料庫

我們終於能夠操作我們的資料庫了。但是所有的操作必須在後臺執行緒中完成。你可以通過使用 AsyncTask , Thread , Handler , RxJava 或其它方式來完成。

如果沒有在後臺執行緒執行,並且也沒有說明可以在主執行緒操作的話,就會報以下錯誤。
Caused by: java.lang.IllegalStateException: Cannot access database on the main thread since it may potentially lock the UI for a long period of time.
例如,我們可以像下面這樣插入資料
        // 由於訪問資料庫要耗費很多時間,有兩個解決方法
        // 第一個方法 databaseBuilder使用allowMainThreadQueries()
        // 以下是第二個方法
        AsyncTask.execute(new Runnable() {
            @Override
            public void run() {
                User user=new User();
                user.setName("Hulk");
                user.setAge(19);
                user.setId(1);
                UserDatabase
                        .getInstance(getApplicationContext())
                        .getUserDao()
                        .delete(user);

//                User user1=new User();
//                user1.setName("name2");
//                user1.setAge(19);
//                UserDatabase
//                        .getInstance(getApplicationContext())
//                        .getUserDao()
//                        .insert(user1);

                List<User> allUsers = UserDatabase
                        .getInstance(getApplicationContext())
                        .getUserDao()
                        .getAllUsers();

                for (User user3:
                        allUsers) {
                    Log.d("name:" + user3.getName(), "age:" + user3.getAge() + "id:" + user3.getId());
                }
            }
        });

留言

這個網誌中的熱門文章

Android - 使用 adb 安装apk

Android ContentProvider 實現多個應用程式共享資料

Android TextView autosizing 自動調整大小