当前位置: 首页 > 知识库问答 >
问题:

如何将服务器端的数据存储到机房数据库中

公良骁
2023-03-14

我在我的android应用程序中使用了reverfit2和Rxjava2作为网络库,NodeJS和MongoDB作为后端服务,我想从服务器获取数据,并将数据存储在房间数据库中,以便如果用户再次打开应用程序,它将从房间获取数据,而不是从服务器获取数据,直到服务器上添加了一些新的数据。

我想达到的目标:

1)从服务器获取数据后,存储在房间数据库中。

2)显示房间数据库中数据,直到服务器上更新了一些新数据。

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();

}

ReverfitClient.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;
}
}
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();

  }
}

谢谢

共有1个答案

程冥夜
2023-03-14

客房基础知识

Room库充当底层SQLite数据库的抽象层。因此,使用Room注释:

  1. 到数据库和实体,其中实体是表示表结构的POJO类。
  2. 指定检索、更新和删除操作。
  3. 添加约束,如外键。
  4. 对LiveData的支持。

tableName属性用于定义每个实体类必须至少有一个主键字段的表名,用@PrimaryKey批注实体类中的字段可以用@ColumnInfo(name=“NAME_OF_COLUMN”)批注,给出特定的列名

DAO:Data Access Object可以是一个接口,也可以是一个带有@DOA注释的抽象类,它包含了定义要对数据执行的操作的所有方法。方法可以用

@query从数据库检索数据

@insert将数据插入数据库

@delete从数据库中删除数据

@update更新数据库中的数据

    dependencies {
    // Room dependencies
      compile 'android.arch.persistence.room:runtime:1.0.0'
      annotationProcessor 'android.arch.persistence.room:compiler:1.0.0'
    }
    @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
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

}

创建数据库

现在,我们将table定义为Entity,并通过NoteDAO定义CRUD方法。数据库拼图的最后一块是数据库本身。

@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;
}

}

实现数据库交互

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();
 类似资料:
  • Room存储数据库的位置以及如何强制重新生成数据库?我尝试在以下位置查找DB: 我想使用SQLLite看看数据库中到底有什么数据,所以我按照“Access database in Android Studio”的方向操作,但我只看到一个缓存和codecache目录存储在那里。没有数据库目录。 想要查看DB的原因是我更改了模型以添加几个字段,但我想不出如何强制使用Room来重新创建并用数据重新填充D

  • 问题内容: 有人可以告诉我,在以下情况下如何进行? 接收文件(MS文件,ODS,PDF) 通过Apache Tika提取公元核心元数据+通过jackrabbit-content-extractors提取内容 使用Jackrabbit将文档(内容)及其元数据存储到存储库中 ? 检索文档+元数据 我对第3点和第4点感兴趣… 详细信息:该应用程序正在以交互方式处理文档(一些分析-语言检测,单词计数等。+

  • 这可能是愚蠢的,但我使用XAMPP在本地主机上使用MySQL,而且我已经完成了我的应用程序并购买了服务器,所以我如何才能上传我的本地主机数据库到服务器?

  • 我创建了一个TextView,它以多行显示值 ,我希望将该值保留在SQLite数据库中。这是我使用的代码: 问题是当我保存值时,整个值被插入到一个单元格中。我希望每行的值分开,然后插入到每行的单个单元格中,尽管我使用扫描器方法插入数据,但它不起作用。那有什么办法吗?

  • 问题内容: 我正在开发一个android应用程序。我想用服务器上的MySQL数据库更新本地SQLite数据库。我不知道哪种方法最合适和最标准? 问题答案: 创建一个Web服务(最好使用REST),然后将SQLite / MySQL数据序列化,然后将其PUT / POST /从Web服务中获取/获取。如果您决定从MySQL切换到其他服务器端,这将为您提供一个很好的抽象层。

  • 我试图找到一种方法来保存复选框的状态到房间数据库,但当我点击复选框并重新打开应用程序时,它的状态并没有改变。我不知道我哪里出错了。我已经搜索了前面的问题,但找不到解决办法。下面是我的代码和感谢。 TodoAdapter 主体活动