詳解Android中Room組件的使用
一.Android官方ORM數(shù)據(jù)庫Room
Android采用Sqlite作為數(shù)據(jù)庫存儲。但由于Sqlite代碼寫起來繁瑣且容易出錯,因此Google推出了Room,其實Room就是在Sqlite上面再封裝了一層。下面是Room的架構(gòu)圖:

要想更好地理解上面的圖,我們先要理解幾個概念:Entity和Dao
Entity:實體,一個entity就對應于數(shù)據(jù)庫中的一張表。Entity類是Sqlite中的表對java類的映射,例如有一個學生表,有id,name,age三個字段;那么對應的就有一個學生類,有id,name,age三個成員變量和學生表中的字段進行一一對應。
Dao:即Data Access Object,數(shù)據(jù)訪問對象,就是字面意思,可以通過他來訪問數(shù)據(jù)庫中的數(shù)據(jù)。
那么所謂的ORM(Object Relational Mapping),對象關系映射,就很好理解了。就是建立一個從數(shù)據(jù)庫表到java類的映射,表中的字段對應類中的成員變量,表中的記錄對應該類的一個實例。
二.Room數(shù)據(jù)庫的基本使用方法
1.在使用Room數(shù)據(jù)庫前,先要在app/build.gradle文件中導入以下的依賴:
implementation 'androidx.room:room-runtime:2.5.2'
annotationProcessor 'androidx.room:room-compiler:2.5.2'
2.創(chuàng)建一個關于學生的Entity,即創(chuàng)建一張學生表:
@Entity
public class Student {
@PrimaryKey
private Integer id;
@ColumnInfo(name="name",typeAffinity = ColumnInfo.TEXT)
private String name;
@ColumnInfo(name="age",typeAffinity = ColumnInfo.INTEGER)
private Integer age;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Student(Integer id, String name, Integer age) {
this.id = id;
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
'}';
}
}@Entity注解用于將Student類和Room數(shù)據(jù)庫中的數(shù)據(jù)表對應起來;@PrimaryKey注解即主鍵約束;@ColumnInfo注解可以設置該成員變量對應的表中字段的名稱以及類型
需要注意的一點是get方法不可省略
3.針對上面的學生類Entity,我們需要定義一個Dao接口文件,以便對數(shù)據(jù)庫進行訪問,在接口的上方加上@Dao注解即可
@Entity
public class Student {
@PrimaryKey
private Integer id;
@ColumnInfo(name="name",typeAffinity = ColumnInfo.TEXT)
private String name;
@ColumnInfo(name="age",typeAffinity = ColumnInfo.INTEGER)
private Integer age;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Student(Integer id, String name, Integer age) {
this.id = id;
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
'}';
}
}4.定義好Entity和Dao后,接下來就是創(chuàng)建數(shù)據(jù)庫了,代碼如下:
@Database(entities = {Student.class},version = 1)
public abstract class MyDatabase extends RoomDatabase {
private static final String DATABASE_NAME="my_db";
private static MyDatabase myDatabase;
public static synchronized MyDatabase getInstance(Context context){
if(myDatabase==null){
myDatabase= Room.databaseBuilder(context,MyDatabase.class,DATABASE_NAME).build();
}
return myDatabase;
}
@Override
public void clearAllTables() {
}
@NonNull
@Override
protected InvalidationTracker createInvalidationTracker() {
return null;
}
@NonNull
@Override
protected SupportSQLiteOpenHelper createOpenHelper(@NonNull DatabaseConfiguration databaseConfiguration) {
return null;
}
public abstract StudentDao studentDao();
}@Database注解用于告訴系統(tǒng)這是Room數(shù)據(jù)庫對象,entities屬性用于指定該數(shù)據(jù)庫有哪些表,version用于指定數(shù)據(jù)庫的版本號數(shù)據(jù)庫類需要繼承RoomDatabase類,并結(jié)合單例模式完成創(chuàng)建。
到這里,數(shù)據(jù)庫和表就創(chuàng)建完成了,接下來就看看如何對數(shù)據(jù)庫進行增刪改查了。
5.結(jié)合ViewModel和LiveData,對數(shù)據(jù)庫進行增刪改查,并且數(shù)據(jù)庫表的記錄發(fā)生變化時,頁面可以及時收到通知,并更新頁面。
LiveData通常和ViewModel一起使用,ViewModel用于存儲頁面的數(shù)據(jù),因此我們可以把數(shù)據(jù)庫的實例化放到ViewModel中,但數(shù)據(jù)庫的實例化需要用到Context對象,因此我們不宜直接用ViewModel,而應該用其子類AndroidViewModel。
public class StudentViewModel extends AndroidViewModel {
private MyDatabase myDatabase;
private LiveData<List<Student>> liveDataStudents;
public StudentViewModel(@NonNull Application application) {
super(application);
myDatabase=MyDatabase.getInstance(application);
liveDataStudents=myDatabase.studentDao().getAllStudents();
}
public LiveData<List<Student>> getLiveDataStudents(){
return liveDataStudents;
}
public void insertStudent(Student student){
myDatabase.studentDao().insertStudent(student);
}
public void deleteStudent(Student student){
myDatabase.studentDao().deleteStudent(student);
}
public void updateStudent(Student student){
myDatabase.studentDao().updataStudent(student);
}
public Student selectStudentById(Integer id){
return myDatabase.studentDao().selectStudentById(id);
}
}6.在Activity中實例化StudentViewModel,并進行增刪改查操作,并監(jiān)聽LiveData的變化。
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private Button btn_insert,btn_delete,btn_update,btn_select;
private TextView tv_display;
private StudentViewModel studentViewModel;
private ExecutorService executor = Executors.newSingleThreadExecutor();
private Student student;
@SuppressLint("MissingInflatedId")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv_display=findViewById(R.id.tv_display);
btn_delete=findViewById(R.id.btn_delete);
btn_insert=findViewById(R.id.btn_insert);
btn_update=findViewById(R.id.btn_update);
btn_select=findViewById(R.id.btn_select);
btn_select.setOnClickListener(this);
btn_insert.setOnClickListener(this);
btn_delete.setOnClickListener(this);
btn_update.setOnClickListener(this);
studentViewModel=new ViewModelProvider(this,new MyViewModelFactory(getApplication())).get(StudentViewModel.class);
studentViewModel.getLiveDataStudents().observe(this, new Observer<List<Student>>() {
@Override
public void onChanged(List<Student> students) {
tv_display.setText(students+"");
}
});
}
@Override
public void onClick(View view) {
switch(view.getId()){
case R.id.btn_delete:
executor.execute(new Runnable() {
@Override
public void run() {
studentViewModel.deleteStudent(new Student(1,"jack",20));
}
});
break;
case R.id.btn_update:
executor.execute(new Runnable() {
@Override
public void run() {
studentViewModel.updateStudent(new Student(1,"zhangsan",32));
}
});
break;
case R.id.btn_insert:
executor.execute(new Runnable() {
@Override
public void run() {
studentViewModel.insertStudent(new Student(1,"lisi",22));
}
});
break;
case R.id.btn_select:
executor.execute(new Runnable() {
@Override
public void run() {
student = studentViewModel.selectStudentById(1);
Log.i("test",student.toString());
}
});
break;
}
}
}public class MyViewModelFactory implements ViewModelProvider.Factory {
private Application application;
public MyViewModelFactory(Application application){
this.application=application;
}
@NonNull
@Override
public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
return (T)new StudentViewModel(application);
}
}運行應用程序,對數(shù)據(jù)庫進行增刪改操作時,onChanged方法就會回調(diào),然后在這個方法中對頁面進行更新即可。
以上就是詳解Android中Room組件的使用的詳細內(nèi)容,更多關于Android Room組件的資料請關注腳本之家其它相關文章!
相關文章
Kotlin Service實現(xiàn)消息推送通知過程
這幾天分析了一下的啟動過程,于是乎,今天寫一下Service使用; 給我的感覺是它并不復雜,千萬不要被一坨一坨的代碼嚇住了,雖然彎彎繞繞不少,重載函數(shù)一個接著一個,就向走迷宮一樣,但只要抓住主線閱讀,很快就能找到出口2022-12-12
Android開發(fā)實現(xiàn)在TextView前面加標簽示例
這篇文章主要為大家介紹了Android開發(fā)實現(xiàn)TextView前面加標簽示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-04-04
解析android 流量監(jiān)測的實現(xiàn)原理
本篇文章是對android中流量監(jiān)測的實現(xiàn)原理進行了詳細的分析介紹,需要的朋友參考下2013-06-06
Flutter?頁面跳轉(zhuǎn)和傳值的實現(xiàn)
跳轉(zhuǎn)傳值是再普通不過的小功能了,在開發(fā)中會經(jīng)常用到,比如列表進入詳情,本文主要介紹了Flutter?頁面跳轉(zhuǎn)和傳值的實現(xiàn),具有一定的參考價值,感興趣的可以了解一下2024-04-04
Android從0到完整項目(1)使用Android studio 創(chuàng)建項目詳解
本篇文章主要介紹了Android從0到完整項目(1)使用Android studio 創(chuàng)建項目詳解,具有一定的參考價值,有興趣的可以了解一下2017-07-07

