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