从服务器获取后如何在会议室数据库中存储数据 [英] How to store data in room database after fetching from server
问题描述
我在Android应用中将Retrofit2和Rxjava2用作网络库,将NodeJS和MongoDB用作后端服务.我想从服务器获取数据并将数据存储在会议室数据库中,以便用户再次打开应用程序来获取数据直到服务器上添加了一些新数据后,才从房间而不是服务器中获取数据.
I am using Retrofit2 and Rxjava2 in my android app as a networking library and NodeJS and MongoDB as a backend service.I want to fetch data from server and store data in room database in order to if user open app again it fetches data from room and not from server until some new data is added on server.
到目前为止,我已经成功地从服务器获取了数据并将其显示在回收站视图中.
So far I have successfully fetched data from server and showing it in recycler view.
我想要实现的目标:
1)从服务器获取数据后,将数据存储在会议室数据库中.
1) Store data in room database after fetching from server.
2)显示会议室数据库中的数据,直到服务器上更新了一些新数据为止.
2) Show data from room database until some new data updated on server.
这是我的下面的代码:
ApiService.java
public interface ApiService {
@POST("retrofitUsers")
@FormUrlEncoded
Observable<String> saveData(@Field("name") String name,
@Field("age") String age);
@GET("getUsers")
Observable<List<BioData>> getData();
}
RetrofitClient.java
public class RetrofitClient {
private static Retrofit retrofit = null;
public static Retrofit getInstance(){
if(retrofit == null)
retrofit = new Retrofit.Builder()
.baseUrl("https://bookbudiapp.herokuapp.com/")
.addConverterFactory(GsonConverterFactory.create(new GsonBuilder().setLenient().create()))
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build();
return retrofit;
}
private RetrofitClient(){
}
}
BioData.java
public class BioData {
@SerializedName("name")
@Expose
private String name;
@SerializedName("age")
@Expose
private String age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
}
MainActivity.java
public class Users extends AppCompatActivity {
RecyclerView recycle;
UserAdapter adapter;
List<BioData> list;
CompositeDisposable compositeDisposable;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recycle = findViewById(R.id.recycle);
recycle.setHasFixedSize(true);
recycle.setLayoutManager(new LinearLayoutManager(this));
list = new ArrayList<>();
compositeDisposable = new CompositeDisposable();
fetchData();
}
private void fetchData(){
Retrofit retrofit = RetrofitClient.getInstance();
ApiService myApi = retrofit.create(ApiService.class);
Disposable disposable = myApi.getData().subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<List<BioData>>() {
@Override
public void accept(List<BioData> bioData) throws Exception {
adapter = new UserAdapter(bioData,getApplicationContext());
recycle.setAdapter(adapter);
}
});
compositeDisposable.add(disposable);
}
@Override
protected void onStop() {
super.onStop();
compositeDisposable.clear();
}
}
如何在我的应用程序中添加Room数据库,让我知道我对此一无所知.
How can I add Room database in my app let me know I have no idea of it any help would be appreciated.
谢谢
推荐答案
房间基础
Room库充当基础SQLite数据库的抽象层.因此,使用了房间注释:
The Room library acts as an abstract layer for underlying SQLite database. Thus, Room annotations are used:
- 到数据库和实体,其中实体是表示表结构的POJO类.
- 指定检索,更新和删除操作.
- 添加约束,例如外键.
- 对LiveData的支持.
会议室中有3个主要组成部分
-
Entity:带有@Entity注释的类被映射到数据库中的表.每个实体都保存在自己的表中,类中的每个字段都代表列名.
Entity : A class annotated with the @Entity annotation is mapped to a table in database. Every entity is persisted in its own table and every field in class represents the column name.
tableName属性用于定义表的名称 每个实体类都必须至少有一个主键字段,并用@PrimaryKey注释 实体类中的字段可以使用@ColumnInfo(name ="name_of_column")批注进行批注,以给出特定的列名
tableName attribute is used to define the name of the table Every entity class must have at-least one Primary Key field, annotated with @PrimaryKey Fields in entity class can be annotated with @ColumnInfo(name = "name_of_column") annotation to give specific column names
DAO:数据访问对象可以是带有@Doa批注的接口或抽象类,其中包含定义用于对数据执行的操作的所有方法.可以用
DAO : Data Access Object is either be an interface or an abstract class annotated with @Doa annotation, containing all the methods to define the operations to be performed on data. The methods can be annotated with
@查询以从数据库检索数据
@Query to retrieve data from database
@插入以将数据插入数据库
@Insert to insert data into database
@Delete从数据库中删除数据
@Delete to delete data from database
@Update以更新数据库中的数据
@Update to update data in database
- 数据库:数据库是表的容器.带有@Database注释的抽象类用于创建具有给定名称以及数据库版本的数据库.
添加这些依赖项:
dependencies {
// Room dependencies
compile 'android.arch.persistence.room:runtime:1.0.0'
annotationProcessor 'android.arch.persistence.room:compiler:1.0.0'
}
创建实体
在创建数据库之前,我们先创建一个名为Note的实体,然后将此类的对象添加到数据库中.
Before creating a database, Let's create an Entity, named as Note and later, Objects of this class will be added to database.
@Entity
public class Note {
@PrimaryKey(autoGenerate = true)
private int note_id;
@ColumnInfo(name = "note_content") // column name will be "note_content" instead of "content" in table
private String content;
private String title;
private
public Note(int note_id, String content, String title) {
this.note_id = note_id;
this.content = content;
this.title = title;
}
public int getNote_id() {
return note_id;
}
public void setNote_id(int note_id) {
this.note_id = note_id;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Note)) return false;
Note note = (Note) o;
if (note_id != note.note_id) return false;
return title != null ? title.equals(note.title) : note.title == null;
}
@Override
public int hashCode() {
int result = note_id;
result = 31 * result + (title != null ? title.hashCode() : 0);
return result;
}
@Override
public String toString() {
return "Note{" +
"note_id=" + note_id +
", content='" + content + '\'' +
", title='" + title + '\'' +
'}';
}}
创建DAO
DAO定义了所有访问数据库的方法,并使用@Dao注释进行了注释. DAO充当对数据库中的数据执行CRUD操作的合同.
DAOs define all methods to access database, annotated with @Dao annotation. The DAO acts as a contract to perform CRUD operations on data within a database.
@Dao
public interface NoteDao {
@Query("SELECT * FROM user "+ Constants.TABLE_NAME_NOTE)
List<Note> getAll();
/*
* Insert the object in database
* @param note, object to be inserted
*/
@Insert
void insert(Note note);
/*
* update the object in database
* @param note, object to be updated
*/
@Update
void update(Note repos);
/*
* delete the object from database
* @param note, object to be deleted
*/
@Delete
void delete(Note note);
/*
* delete list of objects from database
* @param note, array of objects to be deleted
*/
@Delete
void delete(Note... note); // Note... is varargs, here note is an array
}
创建数据库
现在,我们已将表定义为通过NoteDao定义的Entity和CRUD方法.数据库难题的最后一部分是数据库本身.
Now, we have table defined as Entity and CRUD methods defined via NoteDao. The last piece of the database puzzle is the database itself.
@Database(entities = { Note.class }, version = 1)
public abstract class NoteDatabase extends RoomDatabase {
public abstract NoteDao getNoteDao();
private static NoteDatabase noteDB;
public static NoteDatabase getInstance(Context context) {
if (null == noteDB) {
noteDB = buildDatabaseInstance(context);
}
return noteDB;
}
private static NoteDatabase buildDatabaseInstance(Context context) {
return Room.databaseBuilder(context,
NoteDatabase.class,
Constants.DB_NAME)
.allowMainThreadQueries().build();
}
public void cleanUp(){
noteDB = null;
}
}
实现数据库交互
下面的代码片段将演示使用Room数据库进行插入,更新和删除功能的过程.
The below snippet will demonstrate the working of insert, update, and delete functionality using the Room database.
public class AddNoteActivity extends AppCompatActivity {
private TextInputEditText et_title,et_content;
private NoteDatabase noteDatabase;
private Note note;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add_note);
et_title = findViewById(R.id.et_title);
et_content = findViewById(R.id.et_content);
noteDatabase = NoteDatabase.getInstance(AddNoteActivity.this);
Button button = findViewById(R.id.but_save);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// fetch data and create note object
note = new Note(et_content.getText().toString(),
et_title.getText().toString());
// create worker thread to insert data into database
new InsertTask(AddNoteActivity.this,note).execute();
}
});
}
private void setResult(Note note, int flag){
setResult(flag,new Intent().putExtra("note",note));
finish();
}
private static class InsertTask extends AsyncTask<Void,Void,Boolean> {
private WeakReference<AddNoteActivity> activityReference;
private Note note;
// only retain a weak reference to the activity
InsertTask(AddNoteActivity context, Note note) {
activityReference = new WeakReference<>(context);
this.note = note;
}
// doInBackground methods runs on a worker thread
@Override
protected Boolean doInBackground(Void... objs) {
activityReference.get().noteDatabase.getNoteDao().insertNote(note);
return true;
}
// onPostExecute runs on main thread
@Override
protected void onPostExecute(Boolean bool) {
if (bool){
activityReference.get().setResult(note,1);
}
}
}
}
检索并显示记事列表
public class NoteListActivity extends AppCompatActivity implements NotesAdapter.OnNoteItemClick{
private TextView textViewMsg;
private RecyclerView recyclerView;
private NoteDatabase noteDatabase;
private List<Note> notes;
private NotesAdapter notesAdapter;
private int pos;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initializeVies();
displayList();
}
private void displayList(){
// initialize database instance
noteDatabase = NoteDatabase.getInstance(NoteListActivity.this);
// fetch list of notes in background thread
new RetrieveTask(this).execute();
}
private static class RetrieveTask extends AsyncTask<Void,Void,List<Note>>{
private WeakReference<NoteListActivity> activityReference;
// only retain a weak reference to the activity
RetrieveTask(NoteListActivity context) {
activityReference = new WeakReference<>(context);
}
@Override
protected List<Note> doInBackground(Void... voids) {
if (activityReference.get()!=null)
return activityReference.get().noteDatabase.getNoteDao().getNotes();
else
return null;
}
@Override
protected void onPostExecute(List<Note> notes) {
if (notes!=null && notes.size()>0 ){
activityReference.get().notes = notes;
// hides empty text view
activityReference.get().textViewMsg.setVisibility(View.GONE);
// create and set the adapter on RecyclerView instance to display list
activityReference.get().notesAdapter = new NotesAdapter(notes,activityReference.get());
activityReference.get().recyclerView.setAdapter(activityReference.get().notesAdapter);
}
}
}
private void initializeVies(){
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
textViewMsg = (TextView) findViewById(R.id.tv\_\_empty);
// Action button to add note
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(listener);
recyclerView = findViewById(R.id.recycler_view);
recyclerView.setLayoutManager(new LinearLayoutManager(NoteListActivity.this));
}
}
更新说明
public class AddNoteActivity extends AppCompatActivity {
private TextInputEditText et_title,et_content;
private NoteDatabase noteDatabase;
private Note note;
private boolean update;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add_note);
et_title = findViewById(R.id.et_title);
et_content = findViewById(R.id.et_content);
noteDatabase = NoteDatabase.getInstance(AddNoteActivity.this);
Button button = findViewById(R.id.but_save);
if ( (note = (Note) getIntent().getSerializableExtra("note"))!=null ){
getSupportActionBar().setTitle("Update Note");
update = true;
button.setText("Update");
et_title.setText(note.getTitle());
et_content.setText(note.getContent());
}
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
note.setContent(et_content.getText().toString());
note.setTitle(et_title.getText().toString());
noteDatabase.getNoteDao().updateNote(note);
}
});
}
}
删除记事
noteDatabase.getNoteDao().deleteNote(notes.get(pos));
adapterObj.notifyDataSetChanged();
这篇关于从服务器获取后如何在会议室数据库中存储数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!