原文鏈接

前言

Android中提供了SQLite資料庫進行數據的持久化 ,並提供了對應API訪問資料庫,而Room框架提供了SQLite數據訪問抽象層,為高效的資料庫訪問層帶來便捷

APP可以緩存用戶數據,當APP離線時便從SQLite讀取數據,當重新連線時即可完成和伺服器數據的同步

谷歌官方強烈推薦使用Room框架操作SQLite資料庫

Hello World

首先在build.gradle中添加必要依賴

dependencies {
def room_version = "1.1.1"

implementation "android.arch.persistence.room:runtime:$room_version"
annotationProcessor "android.arch.persistence.room:compiler:$room_version" // use kapt for Kotlin

// optional - RxJava support for Room
implementation "android.arch.persistence.room:rxjava2:$room_version"

// optional - Guava support for Room, including Optional and ListenableFuture
implementation "android.arch.persistence.room:guava:$room_version"

// Test helpers
testImplementation "android.arch.persistence.room:testing:$room_version"
}

創建實體類User,@Entity表示該類對應資料庫中的表,@ColumnInfo後面的name屬性對應資料庫中的欄位名,並實現該實體類的GetterSetter方法

@Entity
public class User {
@PrimaryKey
private int uid;

@ColumnInfo(name = "first_name")
private String firstName;

@ColumnInfo(name = "last_name")
private String lastName;

public int getUid() {
return uid;
}

public void setUid(int uid) {
this.uid = uid;
}

public String getFirstName() {
return firstName;
}

public void setFirstName(String firstName) {
this.firstName = firstName;
}

public String getLastName() {
return lastName;
}

public void setLastName(String lastName) {
this.lastName = lastName;
}

@Override
public String toString() {
return "User{" +
"uid=" + uid +
", firstName=" + firstName + +
", lastName=" + lastName + +
};
}
}

創建實體類對應的daoUserDao,完成User的增刪改查(CRUD)介面定義,@Dao註解定義一個dao層,參數賦值(傳遞)使用:clumn_name進行賦值

@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(onConflict = OnConflictStrategy.REPLACE)
void insertAll(User... users);

@Delete
void delete(User user);
}

創建AppDatabase@Database註解表示這是一個資料庫操作類,entities對應Entity實體類,version用於資料庫版本升級,並在該抽象類中定義一個返回dao層的抽象方法

@Database(entities = {User.class}, version = 1, exportSchema = false)
public abstract class AppDatabase extends RoomDatabase {
public abstract UserDao userDao();
}

初始化用於操作資料庫的實例對象AppDatabase,需要注意的是不能在主線程中初始化,必須新開啟一個線程進行初始化,否則會報錯,或者無法創建資料庫

new Thread(new Runnable() {
@Override
public void run() {
AppDatabase db = Room.databaseBuilder(getApplicationContext(),
AppDatabase.class, "database-name").build();
}
}).start();

測試

增加,也可以傳一個User數組

for (int i = 0; i < 10; i++) {
User user = new User();
user.setUid(i);
user.setFirstName("Shell" + i);
user.setLastName("Hub" + i);
insertAll(db, user);
}

如果報以下錯誤,修改dao層的註解為@Insert(onConflict = OnConflictStrategy.REPLACE)

android.database.sqlite.SQLiteConstraintException: UNIQUE constraint failed: User.uid (code 1555 SQLITE_CONSTRAINT_PRIMARYKEY)

查詢所有數據

for (User user : db.userDao().getAll()) {
System.out.println(user);
}

other...

Room單例模式

最好使用設計模式中的單例模式獲取資料庫實例,因為每次獲取資料庫實例都很耗時並且耗內存,我們可以自定義一個類繼承Application並定義一個public static方法獲取資料庫實例

public class App extends Application {
private static Context context;
private static final String DATABASE_NAME = "SHELLHUB";
private static AppDatabase DB_INSTANCE;
@Override
public void onCreate() {
super.onCreate();
context = getApplicationContext();

new Thread(new Runnable() {
@Override
public void run() {
DB_INSTANCE = Room.databaseBuilder(getApplicationContext(),
AppDatabase.class, DATABASE_NAME).build();

}
}).start();
}

public static AppDatabase getDB() {
return DB_INSTANCE;
}
}

推薦閱讀:

相關文章