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

要想更好地理解上面的圖,我們先要理解幾個(gè)概念:Entity和Dao
Entity:實(shí)體,一個(gè)entity就對(duì)應(yīng)于數(shù)據(jù)庫(kù)中的一張表。Entity類是Sqlite中的表對(duì)java類的映射,例如有一個(gè)學(xué)生表,有id,name,age三個(gè)字段;那么對(duì)應(yīng)的就有一個(gè)學(xué)生類,有id,name,age三個(gè)成員變量和學(xué)生表中的字段進(jìn)行一一對(duì)應(yīng)。
Dao:即Data Access Object,數(shù)據(jù)訪問(wèn)對(duì)象,就是字面意思,可以通過(guò)他來(lái)訪問(wèn)數(shù)據(jù)庫(kù)中的數(shù)據(jù)。
那么所謂的ORM(Object Relational Mapping),對(duì)象關(guān)系映射,就很好理解了。就是建立一個(gè)從數(shù)據(jù)庫(kù)表到j(luò)ava類的映射,表中的字段對(duì)應(yīng)類中的成員變量,表中的記錄對(duì)應(yīng)該類的一個(gè)實(shí)例。
二.Room數(shù)據(jù)庫(kù)的基本使用方法
1.在使用Room數(shù)據(jù)庫(kù)前,先要在app/build.gradle文件中導(dǎo)入以下的依賴:
implementation 'androidx.room:room-runtime:2.5.2'
annotationProcessor 'androidx.room:room-compiler:2.5.2'
2.創(chuàng)建一個(gè)關(guān)于學(xué)生的Entity,即創(chuàng)建一張學(xué)生表:
@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ù)庫(kù)中的數(shù)據(jù)表對(duì)應(yīng)起來(lái);@PrimaryKey注解即主鍵約束;@ColumnInfo注解可以設(shè)置該成員變量對(duì)應(yīng)的表中字段的名稱以及類型
需要注意的一點(diǎn)是get方法不可省略
3.針對(duì)上面的學(xué)生類Entity,我們需要定義一個(gè)Dao接口文件,以便對(duì)數(shù)據(jù)庫(kù)進(jìn)行訪問(wèn),在接口的上方加上@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后,接下來(lái)就是創(chuàng)建數(shù)據(jù)庫(kù)了,代碼如下:
@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ù)庫(kù)對(duì)象,entities屬性用于指定該數(shù)據(jù)庫(kù)有哪些表,version用于指定數(shù)據(jù)庫(kù)的版本號(hào)數(shù)據(jù)庫(kù)類需要繼承RoomDatabase類,并結(jié)合單例模式完成創(chuàng)建。
到這里,數(shù)據(jù)庫(kù)和表就創(chuàng)建完成了,接下來(lái)就看看如何對(duì)數(shù)據(jù)庫(kù)進(jìn)行增刪改查了。
5.結(jié)合ViewModel和LiveData,對(duì)數(shù)據(jù)庫(kù)進(jìn)行增刪改查,并且數(shù)據(jù)庫(kù)表的記錄發(fā)生變化時(shí),頁(yè)面可以及時(shí)收到通知,并更新頁(yè)面。
LiveData通常和ViewModel一起使用,ViewModel用于存儲(chǔ)頁(yè)面的數(shù)據(jù),因此我們可以把數(shù)據(jù)庫(kù)的實(shí)例化放到ViewModel中,但數(shù)據(jù)庫(kù)的實(shí)例化需要用到Context對(duì)象,因此我們不宜直接用ViewModel,而應(yīng)該用其子類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中實(shí)例化StudentViewModel,并進(jìn)行增刪改查操作,并監(jiān)聽(tīng)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);
}
}運(yùn)行應(yīng)用程序,對(duì)數(shù)據(jù)庫(kù)進(jìn)行增刪改操作時(shí),onChanged方法就會(huì)回調(diào),然后在這個(gè)方法中對(duì)頁(yè)面進(jìn)行更新即可。
以上就是詳解Android中Room組件的使用的詳細(xì)內(nèi)容,更多關(guān)于Android Room組件的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Kotlin Service實(shí)現(xiàn)消息推送通知過(guò)程
這幾天分析了一下的啟動(dòng)過(guò)程,于是乎,今天寫一下Service使用; 給我的感覺(jué)是它并不復(fù)雜,千萬(wàn)不要被一坨一坨的代碼嚇住了,雖然彎彎繞繞不少,重載函數(shù)一個(gè)接著一個(gè),就向走迷宮一樣,但只要抓住主線閱讀,很快就能找到出口2022-12-12
Flutter進(jìn)階之實(shí)現(xiàn)動(dòng)畫效果(八)
這篇文章主要為大家詳細(xì)介紹了Flutter進(jìn)階之實(shí)現(xiàn)動(dòng)畫效果的第八篇,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-08-08
Android開(kāi)發(fā)實(shí)現(xiàn)在TextView前面加標(biāo)簽示例
這篇文章主要為大家介紹了Android開(kāi)發(fā)實(shí)現(xiàn)TextView前面加標(biāo)簽示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-04-04
Android開(kāi)發(fā)中遇到端口號(hào)占用問(wèn)題解決方法
這篇文章主要介紹了Android開(kāi)發(fā)中遇到端口號(hào)占用問(wèn)題解決方法,本文給出了一個(gè)簡(jiǎn)潔實(shí)用的方法來(lái)解決這個(gè)煩人的問(wèn)題,需要的朋友可以參考下2015-06-06
Android ViewFlipper的詳解及實(shí)例
這篇文章主要介紹了Android ViewFlipper的詳解及實(shí)例的相關(guān)資料,通過(guò)本文希望能幫助大家理解這部分內(nèi)容,需要的朋友可以參考下2017-08-08
解析android 流量監(jiān)測(cè)的實(shí)現(xiàn)原理
本篇文章是對(duì)android中流量監(jiān)測(cè)的實(shí)現(xiàn)原理進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-06-06
Flutter?頁(yè)面跳轉(zhuǎn)和傳值的實(shí)現(xiàn)
跳轉(zhuǎn)傳值是再普通不過(guò)的小功能了,在開(kāi)發(fā)中會(huì)經(jīng)常用到,比如列表進(jìn)入詳情,本文主要介紹了Flutter?頁(yè)面跳轉(zhuǎn)和傳值的實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下2024-04-04
Android從0到完整項(xiàng)目(1)使用Android studio 創(chuàng)建項(xiàng)目詳解
本篇文章主要介紹了Android從0到完整項(xiàng)目(1)使用Android studio 創(chuàng)建項(xiàng)目詳解,具有一定的參考價(jià)值,有興趣的可以了解一下2017-07-07
Android實(shí)現(xiàn)文字滾動(dòng)播放效果的代碼
這篇文章主要介紹了Android實(shí)現(xiàn)文字滾動(dòng)播放效果,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-07-07
Android實(shí)現(xiàn)支付寶AR掃描動(dòng)畫效果
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)支付寶AR掃描動(dòng)畫效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-02-02

