簡體   English   中英

實施房間數據庫 (Android)

[英]Implementing the Room Database (Android)

我想知道如何在 Android 應用程序中正確集成 Room Library。 我看到的一些文章使用 Singleton 方法,使用 Respository 進行數據庫調用,而其他文章則使用某種形式的 Dependecy Injection (Dagger 2)。 我想知道這個庫的正確集成?

謝謝

房間基礎

Room 庫充當底層 SQLite 數據庫的抽象層。 因此,使用 Room 注釋:

  1. 到數據庫和實體,其中實體是表示表結構的 POJO 類。
  2. 指定檢索、更新和刪除操作。
  3. 添加約束,例如外鍵。
  4. 支持 LiveData。

Room 有 3 個主要組件

  1. 實體:用@Entity 注釋的類映射到數據庫中的表。 每個實體都保存在自己的表中,類中的每個字段都代表列名。

tableName 屬性用於定義表的名稱 每個實體類必須至少有一個 Primary Key 字段,用 @PrimaryKey 注釋 實體類中的字段可以用 @ColumnInfo(name = “name_of_column”) 注釋給出特定列名字

  1. DAO :數據訪問對象要么是一個接口,要么是一個用@Doa 注釋的抽象類,包含定義要對數據執行的操作的所有方法。 方法可以用注釋

@Query 從數據庫中檢索數據

@Insert 將數據插入數據庫

@Delete 從數據庫中刪除數據

@Update 更新數據庫中的數據

  1. 數據庫:數據庫是表的容器。 使用@Database 注釋的抽象類用於創建具有給定名稱和數據庫版本的數據庫。

為了更好地理解看這張圖

添加這些依賴項:

    dependencies {
    // Room dependencies
      compile 'android.arch.persistence.room:runtime:1.0.0'
      annotationProcessor 'android.arch.persistence.room:compiler:1.0.0'
    }

創建實體

在創建數據庫之前,讓我們創建一個實體,命名為 Note,稍后,該類的對象將被添加到數據庫中。

    @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 操作的合約。

    @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 定義了 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;
}

}

實現數據庫交互

下面的代碼片段將演示使用 Room 數據庫的插入、更新和刪除功能的工作。

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

}

}

檢索和顯示 NoteList

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 是 Android 開發中 SQLite 數據庫的 ORM(對象關系映射器),也是 Android Jetpack 的一部分。
  • 在 SQLite 數據庫上提供抽象層
  • 樣板代碼量減少
  • SQL 查詢的編譯時驗證

ROOM 數據庫組件

  • 它有 3 個主要組件實體、數據庫、DAO。
  • Entity是用@Entity 注解的數據類,就像在 SQLite 中創建一個表,模型類中的變量就像表中的列。
  • Database是一個抽象類,它擴展了 RoomDatabase 並具有與數據庫關聯的實體列表。
  • DAO(數據訪問對象)是一個接口,它定義了要在我們的數據庫中執行的操作。

ROOM 數據庫實現

  • Step 1 創建實體數據類

    @Entity(tableName = "yourOwnTableName")

    數據類 LocalData(

     val column1: String?, val column2: String?, @PrimaryKey(autoGenerate = true) val product_local_id: Int?= null

    )

  • 步驟 2 創建數據庫

    @Database(實體 = [LocalData::class],版本 = 1,exportSchema = false)@TypeConverters

    抽象類 LocalDB : RoomDatabase() {

     abstract fun localDataDao() : LocalDataDAO companion object{ private var instance : LocalDB ? = null fun getInstance(context: Context) : LocalDB ?{ if(instance == null){ synchronized(LocalDB ::class){ instance = Room.databaseBuilder(context.applicationContext, LocalDB::class.java, "localBD.db").allowMainThreadQueries().build() } } return instance } fun destroyInstance(){ instance = null } }

    }

  • 步驟 3 創建DAO

    @Dao 接口 LocalDAO {

     @Insert fun insertData(productEntity: LocalData) : Long @Delete fun deleteData(productEntity: LocalData) : Int @Query("Select * from yourOwnTableName") fun showAllProducts(): List<LocalData> @Query("SELECT COUNT(*) FROM yourOwnTableName") fun totalProducts(): Long

    }

  • 第 4 步是可選的,是創建存儲庫

類 ProductRepository(上下文:上下文){

var dbms : LocalDAO = LocalDB.getInstance(context)?.localDataDao()!!

fun insertData(productEntity: LocalData) : Long{
    return dbms.insertData(productEntity)
}

fun deleteData(productEntity: LocalData) : Int{
    return dbms.deleteData(productEntity)
}

fun getAllData() : List<LocalData> {
    return dbms.showAllProducts()
}

fun checkProductExist(id : Int) : Boolean{
    return dbms.exists(id)
}

fun totalProductsInCart() : Long{
    return dbms.totalProducts()
}

}

step1 在您的 build.gradle 中添加依賴項

def room_version = "2.2.5"

//better to replace new version
implementation "android.arch.lifecycle:extensions:1.1.0"
implementation "androidx.room:room-runtime:$room_version"
implementation "androidx.room:room-rxjava2:$room_version"
implementation "androidx.room:room-guava:$room_version"

// ViewModel
implementation "androidx.lifecycle:lifecycle-viewmodel:2.3.1"
// LiveData
implementation "androidx.lifecycle:lifecycle-livedata:2.3.1"


annotationProcessor "androidx.room:room-compiler:$room_version"
testImplementation "androidx.room:room-testing:$room_version"

我認為最好的地方是 codelabs,它有一個簡單的實現,也有一個更復雜的實現 全部使用Room。

編輯:上面的鏈接似乎已被刪除。 以下是一些替代資源的資源:

  1. 景觀房
  2. Room + LiveData + ViewModel

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM