詳解Android中Room組件的使用
一.Android官方ORM數(shù)據庫Room
Android采用Sqlite作為數(shù)據庫存儲。但由于Sqlite代碼寫起來繁瑣且容易出錯,因此Google推出了Room,其實Room就是在Sqlite上面再封裝了一層。下面是Room的架構圖:
要想更好地理解上面的圖,我們先要理解幾個概念:Entity和Dao
Entity:實體,一個entity就對應于數(shù)據庫中的一張表。Entity類是Sqlite中的表對java類的映射,例如有一個學生表,有id,name,age三個字段;那么對應的就有一個學生類,有id,name,age三個成員變量和學生表中的字段進行一一對應。
Dao:即Data Access Object,數(shù)據訪問對象,就是字面意思,可以通過他來訪問數(shù)據庫中的數(shù)據。
那么所謂的ORM(Object Relational Mapping),對象關系映射,就很好理解了。就是建立一個從數(shù)據庫表到java類的映射,表中的字段對應類中的成員變量,表中的記錄對應該類的一個實例。
二.Room數(shù)據庫的基本使用方法
1.在使用Room數(shù)據庫前,先要在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ù)據庫中的數(shù)據表對應起來;@PrimaryKey注解即主鍵約束;@ColumnInfo注解可以設置該成員變量對應的表中字段的名稱以及類型
需要注意的一點是get方法不可省略
3.針對上面的學生類Entity,我們需要定義一個Dao接口文件,以便對數(shù)據庫進行訪問,在接口的上方加上@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ù)據庫了,代碼如下:
@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ù)據庫對象,entities屬性用于指定該數(shù)據庫有哪些表,version用于指定數(shù)據庫的版本號數(shù)據庫類需要繼承RoomDatabase類,并結合單例模式完成創(chuàng)建。
到這里,數(shù)據庫和表就創(chuàng)建完成了,接下來就看看如何對數(shù)據庫進行增刪改查了。
5.結合ViewModel和LiveData,對數(shù)據庫進行增刪改查,并且數(shù)據庫表的記錄發(fā)生變化時,頁面可以及時收到通知,并更新頁面。
LiveData通常和ViewModel一起使用,ViewModel用于存儲頁面的數(shù)據,因此我們可以把數(shù)據庫的實例化放到ViewModel中,但數(shù)據庫的實例化需要用到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ù)據庫進行增刪改操作時,onChanged方法就會回調,然后在這個方法中對頁面進行更新即可。
以上就是詳解Android中Room組件的使用的詳細內容,更多關于Android Room組件的資料請關注腳本之家其它相關文章!
相關文章
Kotlin Service實現(xiàn)消息推送通知過程
這幾天分析了一下的啟動過程,于是乎,今天寫一下Service使用; 給我的感覺是它并不復雜,千萬不要被一坨一坨的代碼嚇住了,雖然彎彎繞繞不少,重載函數(shù)一個接著一個,就向走迷宮一樣,但只要抓住主線閱讀,很快就能找到出口2022-12-12Android開發(fā)實現(xiàn)在TextView前面加標簽示例
這篇文章主要為大家介紹了Android開發(fā)實現(xiàn)TextView前面加標簽示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-04-04解析android 流量監(jiān)測的實現(xiàn)原理
本篇文章是對android中流量監(jiān)測的實現(xiàn)原理進行了詳細的分析介紹,需要的朋友參考下2013-06-06Android從0到完整項目(1)使用Android studio 創(chuàng)建項目詳解
本篇文章主要介紹了Android從0到完整項目(1)使用Android studio 創(chuàng)建項目詳解,具有一定的參考價值,有興趣的可以了解一下2017-07-07