Android Jetpack中Room的使用
Room
Room主要分三個部分 database、dao和實體類entity
Entity
entity實體類定義時需要用到@Entity(tableName = “student”)註解,其中參數為表名
主鍵定義需要用到@PrimaryKey(autoGenerate = true)註解,參數決定是否自增長
每個屬性(也就是表的字段)都需要加@ColumnInfo(name = “name”,typeAffinity = ColumnInfo.TEXT)註解 ,name是表中的字段名、 typeAffinity是字段類型,類型有:
// 未定義類型關聯。將基於類型進行解析。 int UNDEFINED = 1; // 文本類型 int TEXT = 2; // 整數或佈爾值的列關聯常數。 int INTEGER = 3; // 用於浮點數或雙精度數的列關聯常數。 int REAL = 4; // 二進制數據的列親和常數。 int BLOB = 5;
實體類需要指定一個構造方法。如果我們有多個構造方法,那麼就需要告訴room忽略其他的構造器,不然會報錯,room隻可以使用一個構造器。構造函數上加入@Ignore註解即可(想忽略一個屬性也是)
@Entity(tableName = "student") public class Student { @PrimaryKey(autoGenerate = true) @ColumnInfo(name = "id",typeAffinity = ColumnInfo.INTEGER) public int id; @ColumnInfo(name = "name",typeAffinity = ColumnInfo.TEXT) public String name; @ColumnInfo(name = "age",typeAffinity = ColumnInfo.INTEGER) public int age; @ColumnInfo(name = "sex",typeAffinity = ColumnInfo.INTEGER) public int sex; @Ignore// 告訴room忽略這個構造方法 public Student(int id, String name, int age) { this.id = id; this.name = name; this.age = age; } @Ignore// 告訴room忽略這個構造方法 public Student(int id) { this.id = id; } // 指定room用的構造方法 public Student(String name, int age) { this.name = name; this.age = age; } }
Dao
dao是一個interface,需要加入一個@Dao註解,內部主要聲明一些對數據做操作的抽象方法,方法都需要加上room中特定的註解
@Insert 添加
@Update 修改
@Delete 刪除
@Query 查詢 此註解需要加入參數 參數就是sql語句
@Dao public interface StudentDao { @Insert void insertStudent(Student...students); @Query("SELECT * FROM student") List<Student> getAllStudent(); @Query("SELECT * FROM student WHERE id=:id") List<Student> getAllStudentById(int id); @Query("DELETE FROM student") void clearAll(); @Update void upData(Student...students); @Delete void delete(Student...students); }
DataBase
database類需要繼承RoomDatabase這個抽象類,dataBase也必須是抽象類。需要加入@DataBase註解
@Database(entities = {Student.class}, version = 1, exportSchema = false) // entities-實體類 version-數據庫版本 exportSchema-是否生成schema文件,schema文件中包含的是表結構和信息
如果想生成schema文件 還需要在build.gradle中指定schema文件的生成位置
android { compileSdkVersion 30 buildToolsVersion "30.0.3" defaultConfig { applicationId "com.example.room" minSdkVersion 20 targetSdkVersion 30 versionCode 1 versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" //指定room.schemaLocation生成的文件路徑 javaCompileOptions { annotationProcessorOptions { arguments = ["room.schemaLocation": "$projectDir/schemas".toString()] } } } }
database類需要是單例的 但是不需要寫私有構造器,繼承瞭RoomDatabase之後room會識別,隻需要一個getInstance方法,內部是database的實例化。
public static synchronized StudentDataBase getInstance(Context context) { if (mInstance == null) { mInstance = Room.databaseBuilder(context.getApplicationContext(), StudentDataBase.class, DATABASE_NAME) // .allowMainThreadQueries()// 允許在主線程操作數據庫 .addMigrations(MIGRATION_1_2)// 數據庫升級時 .fallbackToDestructiveMigration()// 數據庫版本異常時 會清空原來的數據 然後轉到目前版本 // .createFromAsset("資源文件中的初始數據庫")// 預填充數據庫 初始數據 .build(); } return mInstance; }
還需要聲明一個獲取dao的抽象方法,隻聲明即可。
public abstract StudentDao getStudentDao();
當數據庫的版本有升級時,就需要使用到Migration,創建Migration(),參數為哪個版本到哪個版本的升級。重寫mingrate方法,在mingrate方法內通過database.execSQL()方法來寫表的變化(結構變化等)。Migration可以有多個,對應表的多次升級。
static final Migration MIGRATION_1_2 = new Migration(1, 2) { @Override public void migrate(@NonNull SupportSQLiteDatabase database) { database.execSQL("ALTER TABLE student ADD COLUMN sex INTEGER NOT NULL DEFAULT 1");// 添加表字段 } };
database全貌
@Database(entities = {Student.class}, version = 1, exportSchema = true) public abstract class StudentDataBase extends RoomDatabase { private static StudentDataBase mInstance; private static final String DATABASE_NAME = "student.db"; public static synchronized StudentDataBase getInstance(Context context) { if (mInstance == null) { mInstance = Room.databaseBuilder(context.getApplicationContext(), StudentDataBase.class, DATABASE_NAME) // .allowMainThreadQueries()// 允許在主線程操作數據庫 .addMigrations(MIGRATION_1_2)// 數據庫升級時 .fallbackToDestructiveMigration()// 數據庫版本異常時 會清空原來的數據 然後轉到目前版本 // .createFromAsset("資源文件中的初始數據庫")// 預填充數據庫 初始數據 .build(); } return mInstance; } static final Migration MIGRATION_1_2 = new Migration(1, 2) { @Override public void migrate(@NonNull SupportSQLiteDatabase database) { database.execSQL("ALTER TABLE student ADD COLUMN sex INTEGER NOT NULL DEFAULT 1");// 添加表字段 } }; public abstract StudentDao getStudentDao(); }
使用
獲取dao
StudentDataBase dataBase = StudentDataBase.getInstance(this); StudentDao studentDao = dataBase.getStudentDao();
通過dao操作表,註意對數據庫的操作需要放到子線程中操作
class GetAllStudentTask extends AsyncTask<Void,Void,List<Student>>{ @Override protected List<Student> doInBackground(Void... voids) { List<Student> allStudent = studentDao.getAllStudent(); for (int j = 0; j < allStudent.size(); j++) { Log.i("student", "doInBackground: "+allStudent.get(j).name+"--id:"+allStudent.get(j).id); } return allStudent; }
到此這篇關於Jetpack中Room的使用的文章就介紹到這瞭,更多相關Jetpack中Room使用內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- 快速瞭解Android Room使用細則
- Android開發Jetpack組件Room用例講解
- 快速瞭解Android Room使用細則進階
- idea使用Mybatis逆向工程插件詳情
- Android Room數據庫加密詳解