Room
https://developer.android.google.cn/topic/libraries/architecture/room
Room重要概念:
Entity:实体类,对应的是数据库的一张表结构,使用注解@Entity标记>
Dao:包含访问一系列访问数据库的方法,使用注解@Dao标记。//Data Access Objects
Database:数据库持有者,作为与应用持久化相关数据的底层连接的主要接入点。使用注解@Database标记,另外需满足以下条件:定义的类必须是一个继承于RoomDatabase的抽象类,在注解中需要定义与数据库相关联的实体类列表。包含一个没有参数的抽象方法并且返回一个Dao对象。
app从Database得到get DAO,从DAO得到Entity,从Entity得到和设置对象值
implementation 'androidx.room: room-runtime: 2.2.5'
//注解器:抽象类自动生成实现类
annotationProcessor 'androidx .room:room-compiler:2.2.5'
Entity
@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 = "name",typeAffinity = ColumnInfo.TEXT)
public int age;
public student (int id,String name, int age){
this.id = id;
this.name = name;
this.age = age;
}
@Ignores
public student (string name, int age) {
this.name = name;
this.age = age;
}
Dao:增删查改接口类
@Dao
public interface StudentDao {
@Insert
void insertStudent (student. .- students) ;
@Delete
void deletestudent (student. . . students);
@Update
void updateStudent (Student . . . students) ;
@Query ( "SELECT *FROMstudent")
List<Student> getAllstudent ();
@Query ("SELECT * FROM student WHERE id = :id")
List<Student> getStudentById(int id);
}
Database
@Database (entities = {Student.class}, version = 1, exportSchema = false)
public abstract class MyDatabase extends RoomDatabase {
private static final string DATABASE_NAME= "my_db. db"
private static MyDatabase mInstance;
public static synchronized MyDatabase getInstance (Context context) {
if (mInstance == nul1) {
mInstance = Room. databaseBuilder(context.getApplicationContext(),
MyDatabase.class,
DATABASE_NAME').build() ;
}
return minstance;
}
public abstract StudentDao getStudentDao ();
}
使用
MyDatabase database = MyDatabase.getInstance (this);
studentDao = database.getStudentDao ( ) ;
public void mlnsert (View view){
student s1 = new Student ( name: "Jack" , age: 20) ;
Student s2 = new Student( name: "Rose",age: 1 ;new
InsertStudentTask (studentDao).execute (s1);
}
class InsertStudentTask extends AsyncTask<Student, Void,void> {
private studentDao studentDao;
public InsertStudentTask (StudentDao studentDao){
this . studentDao - studentDao;
}
@override
protected Void doInBackground (Student. . . students) {
studentDao.insertStudent ( students) ;
rerurn null;
}
}
进一步优化
问题:每当数据库数据发生变化时,都需要开启一个工作线程去重新获取数据库中的数据。 解决:当数据发生变化时,通过LiveData通知View层,实现数据自动更新。
Room+ViewModel+LiveData
public class studentRepository {
private StudentDao studentDao;
public StudentRepository (Context context){
MyDatabase database = MyDatabase.getInstance ( context) ;
this.studentDao = database.getStudentDao ( ) ;
}
public void insertStudent (Student. . . students){
new InsertStudentTask(studentDao) .execute (students);
}
class InsertStudentTask extends AsyncTask<Student, Void,Void> {
private studentDao studentDao;
public InsertStudentTask(StudentDao studentDao) {
this.studentDa
@override
protected Void doInBackground (Student. . . students) {
studentDao.insertstudent (students) ;
return nul1;
}
}
}
public class studentViewModel extends AndroidViewModel {
private studentRepository repository ;
public StudentViewModel ( @NonNull Application application) {
super(application) ;
this.repository = new StudentRepository(application) ;
}
public void insertStudent (Student. . . students) {
repository.insertStudent(students) ;
}
}
studentViewModel = new ViewModelProvider ( owner: this, new
ViewModelProvider.AndroidviewModelFactory(getApplication()).get(StudentViewModel.class)
studentViewModel.getAllStudentsLive () .observe ( owner: this,new Observer<List<Student>>()
@override
public void onChanged (List<Student> students){
adapter.setstudents ( students ) ;
adapter.notifyDataSetChanged ( );
});
}
public void mInsert (View view) {
Student s1 = new student ( name: "Jack", age: 20) ;
Student s2 = new Student ( name: "Rose", age: 18);
studentviewModel .insertStudent (s1,s2) ;
}
room版本升级
1.构造Migration
static final Migration MIGRATION_1_2 = new Migration (1,2){
@override
public void migrate (@NonNull SupportSQLiteDatabase database){
database.execSQL ( "ALTERTABLE student ADD COLUMN sex INTEGER NOT NULLDEFAULT 1" );
};
2.添加addMigrations
public static synchronized MyDatabase getInstance (Context context){
if ( mInstance -= nul1){
mInstance = Room. databaseBuilder(context.getapplicationContext(),
MyDatabase.class,
DATABASE_NAME)
.addMigrations (MIGRATION_1_2,MIGRATION_2_3)
.build () ;
}
return mlnstance;
}
3.修改注解
@Database (entities = {Student.class}, version = 2, exportSchema = false)
使用Migration升级数据库
问题:如果用户设备上数据库版本为1,而当前要安装的App数据库版本为3,怎么办? Room会先判断当前有没有直接从1到3的升级方案,如果有,就直接执行从1到3的升级方案,如果没有,那么Room会按照顺序先后执行Migration(1,2)、Migration(2,3)以完成升级。
|