Jetpack中Room使用 Android Jetpack中Room的使用
IT_zhazhanan 人气:0Room
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; }
加载全部内容