天天看點

Android Jetpack系列(一) Room

Android Jetpack系列(一) Room

    • 前言
    • Room簡介
    • Room使用
      • 1 引用
      • 2 編寫Entity實體類
      • 2 編寫Dao資料操作類
      • 3 編寫Database資料庫操作類
      • 4 調用
    • 示例

前言

  • Jetpack是2017年谷歌在開發者大會上釋出的一套開發工具。
  • Jetpack共包含4個部分:Architecture、Foundation、Behavior 以及 UI 。
  • 其中的Architecture又稱為AAC(Android Architecture Components),是谷歌推薦的android開發架構方案。
  • 此篇文章主要介紹Architecture中的Room
    Android Jetpack系列(一) Room

Room簡介

  • Room 是Google為了簡化舊式的SQLite操作專門提供的一個覆寫SQLite抽象層架構庫;
  • 通過使用注解的方式,能夠非常簡單的實作SQLite的增、删、查、改功能;
  • 功能強大,覆寫SQLite的所有功能(表操作、版本更新等)。

組成部分及功能:

  • Entity : 實體類,資料表對應到實體類的映射。
  • Dao : 資料操作類,包含用于通路資料庫的方法。
  • Database : 資料庫持有者 & 資料庫版本管理者。
  • Room : 資料庫的建立者 & 負責資料庫版本更新的具體實作者。

Room使用

1 引用

// room
    implementation "android.arch.persistence.room:runtime:1.1.1"
    annotationProcessor "android.arch.persistence.room:compiler:1.1.1"

    // 可選項 - Room适配Rxjava元件
    implementation "android.arch.persistence.room:rxjava2:1.1.1"

    // 可選項 - Guava support for Room, including Optional and ListenableFuture
    implementation "android.arch.persistence.room:guava:1.1.1"

    // Test helpers
    testImplementation "android.arch.persistence.room:testing:1.1.1"
    
           

2 編寫Entity實體類

@Data
@Entity(tableName = "USER")
public class UserModel {
    @PrimaryKey
    @ColumnInfo(name = "USER_ID")
    public int id;
    @ColumnInfo(name = "NAME")
    public String name;
    @ColumnInfo(name = "AGE")
    public int age;
    @ColumnInfo(name = "ADDRESS")
    public String address;
    @Ignore
    public String phone;
}

           

其中使用到的注解:

  • @Entity :資料表的實體類,tableName指定了表名。
  • @PrimaryKey :表的主鍵。
  • @ColumnInfo :指定字段名,不加此标注則字段名取變量名。
  • @Ignore :标注此字段不需要添加到資料表中。

還有其他注釋:

  • @Embedded :實體類中引用其他實體類。
  • @ForeignKey :外鍵限制。

2 編寫Dao資料操作類

@Dao
public interface UserDao {

    @Query("SELECT * FROM USER")
    List<UserModel> getAllUsers();

    @Query("SELECT * FROM USER WHERE USER_ID = :id")
    UserModel getUserById(int id);

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    void insertUser(UserModel userModel);

    @Query("UPDATE USER SET NAME = :name AND PHONE = :phone WHERE USER_ID = :id")
    void updateUser(int id, String name, String phone);

    @Update(onConflict =  OnConflictStrategy.REPLACE)
    void updateUsers(UserModel... users);

    @Query("DELETE FROM USER WHERE USER_ID = :id")
    void deleteUserById(int id);

    @Delete
    void deleteUsers(UserModel... users);
}

           

注解說明:

  • @Dao:标注資料庫操作的類。
  • @Query:包含所有Sqlite語句操作。其中帶參數的查詢可參考getUserById方法。
  • @Insert:标注資料庫的插入操作。
  • @Delete:标注資料庫的删除操作。
  • @Update:标注資料庫的更新操作。

3 編寫Database資料庫操作類

為了防止頻繁建立Database類,我在這裡使用了單例模式,加快資料庫通路速度。

@Database(entities = {UserModel.class}, version = 1)
public abstract class MyDataBase extends RoomDatabase {

    private static MyDataBase instance;

    public static MyDataBase getInstance(Context context) {
        if (instance == null) {
            instance = Room.databaseBuilder(context.getApplicationContext(), MyDataBase.class, "mydata.db").allowMainThreadQueries().build();
        }
        return instance;
    }

    public abstract UserDao userDao();
}

           

在建立RoomDatabase時,databaseBuilder可以接多個方法對RoomDatabase進行設定:

/**
     * 預設值是FrameworkSQLiteOpenHelperFactory,設定資料庫的factory。比如我們想改變資料庫的存儲路徑可以通過這個函數來實作
     */
    public RoomDatabase.Builder<T> openHelperFactory(@Nullable SupportSQLiteOpenHelper.Factory factory);

    /**
     * 設定資料庫更新(遷移)的邏輯
     */
    public RoomDatabase.Builder<T> addMigrations(@NonNull Migration... migrations);

    /**
     * 設定是否允許在主線程做查詢操作
     */
    public RoomDatabase.Builder<T> allowMainThreadQueries();

    /**
     * 設定資料庫的日志模式
     */
    public RoomDatabase.Builder<T> setJournalMode(@NonNull JournalMode journalMode);

    /**
     * 設定遷移資料庫如果發生錯誤,将會重新建立資料庫,而不是發生崩潰
     */
    public RoomDatabase.Builder<T> fallbackToDestructiveMigration();

    /**
     * 設定從某個版本開始遷移資料庫如果發生錯誤,将會重新建立資料庫,而不是發生崩潰
     */
    public RoomDatabase.Builder<T> fallbackToDestructiveMigrationFrom(int... startVersions);

    /**
     * 監聽資料庫,建立和打開的操作
     */
    public RoomDatabase.Builder<T> addCallback(@NonNull RoomDatabase.Callback callback);
    
           

4 調用

在activity中調用:

public class MainActivity extends AppCompatActivity {

    @BindView(R.id.input_et)
    EditText inputET;
    @BindView(R.id.result_tv)
    TextView resultTV;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);
    }

    @OnClick(R.id.set_btn)
    void setUser() {
        String name = inputET.getText().toString();
        UserModel userModel = new UserModel();
        userModel.setName(name);
        userModel.setAddress("山東青島");
        userModel.setAge(99);
        userModel.setPhone("15006512345");
        MyDataBase.getInstance(this).userDao().insertUser(userModel);
    }

    @OnClick(R.id.get_btn)
    void getUser(View v) {
        List<UserModel> users = MyDataBase.getInstance(this).userDao().getAllUsers();
        if (users != null && users.size() > 0) {
            resultTV.setText(users.get(0).getName());
        }
    }
}

           

示例

文中所寫參考代碼下載下傳位址:下載下傳

作者簡介 :遊逸,進階軟體工程師,5年開發經驗,微信公衆号【逸遊源碼彙】,喜歡分享幹貨與關注技術前沿,歡迎關注公衆号一起交流學習