原文鏈接
Android中提供了SQLite資料庫進行數據的持久化 ,並提供了對應API訪問資料庫,而Room框架提供了SQLite數據訪問抽象層,為高效的資料庫訪問層帶來便捷
APP可以緩存用戶數據,當APP離線時便從SQLite讀取數據,當重新連線時即可完成和伺服器數據的同步
谷歌官方強烈推薦使用Room框架操作SQLite資料庫
首先在build.gradle中添加必要依賴
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屬性對應資料庫中的欄位名,並實現該實體類的Getter,Setter方法
User
@Entity
@ColumnInfo
name
Getter
Setter
@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 + + }; } }
創建實體類對應的dao層UserDao,完成User的增刪改查(CRUD)介面定義,@Dao註解定義一個dao層,參數賦值(傳遞)使用:clumn_name進行賦值
dao
UserDao
CRUD
@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層的抽象方法
AppDatabase
@Database
entities
Entity
version
@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)
@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...
最好使用設計模式中的單例模式獲取資料庫實例,因為每次獲取資料庫實例都很耗時並且耗內存,我們可以自定義一個類繼承Application並定義一個public static方法獲取資料庫實例
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; } }
推薦閱讀: