Simple DAO CRUD関数を含む
FeedEntryDAO.Java
@Dao
public interface FeedEntryDAO {
@Query("SELECT * FROM feedEntrys")
LiveData<List<FeedEntry>> getAll();
@Query("SELECT * FROM feedEntrys WHERE uid = :uid LIMIT 1")
LiveData<FeedEntry> findByUid(int uid);
@Insert
void insertAll(FeedEntry... feedEntries);
@Delete
void delete(FeedEntry feedEntry);
@Update
int update(FeedEntry feedEntry);
}
select
の場合、LiveDataタイプを返してもかまいません。
アクティビティ内のコードは選択に適しています
viewModel.getFeedEntrys().observe(this,entries -> {...});
ただし、データを挿入、更新、削除しようとすると。コードは少しいようで、毎回asynctaskを作成します。
new AsyncTask<FeedEntry, Void, Void>() {
@Override
protected Void doInBackground(FeedEntry... feedEntries) {
viewModel.update(feedEntries[0]);
return null;
}
}.execute(feedEntry);
私はそれについて2つの質問があります:
提案やアドバイスに感謝します。ありがとうございました。
- LiveDataを使用して、削除、挿入、更新の呼び出しをラップできますか?
いいえ、できません。 issue への回答を書きました。その理由は、LiveDataが変更の通知に使用されるためです。挿入、更新、削除は変更をトリガーしません。削除された行、挿入されたID、または影響を受けた行を返します。恐ろしく見えても、LiveDataを自分のものに巻き付けないことは理にかなっています。とにかく、呼び出しの周りにSingleのようなものを置いて、操作をRX-Java操作でトリガーして操作できるようにすることは理にかなっています。
これらの呼び出しをトリガーする場合は、一部またはすべてのデータを更新、挿入、または削除したことをLiveData onecに通知する選択クエリを確認します。
- 削除、挿入、更新のためにそのようなasynctaskクラスを維持するより良い方法は?
あなたの例を見ると、(Model/View /)ViewModel-Patternを誤用しているように見えます。ビューでリポジトリにアクセスしないでください。サンプルに表示されないため、これを実行しているかどうかはわかりません。とにかく、LiveDataを観察して結果を取得した後、AsyncTaskでviewModel内のデータの更新をラップする必要はありません。つまり、あなたは常に世話をする必要があることを意味します
a)ビュー<->ビューモデル<->リポジトリであり、ビュー<->リポジトリおよびビュー<->ビューモデルではありません
そして
b)不要なスレッドを使用しようとしないでください。デフォルトでバックグラウンドスレッド(@WorkerThread)でLiveDataを監視し(@MainThreadアノテーションが付いていない場合)、ui-thread(@MainThread)で値を取得します。
2番目の質問には、 AsyncTask ;に代わるもう1つの代替手段があります。 Java Executor
を使用しているため、すべてのCRUD操作でExecutor
の複数のインスタンスの代わりにAsyncTask
の単一のインスタンスを使用できます。
デモの例
public class Repository {
private static Repository instance;
private MyDatabase mDatabase;
private Executor mExecutor = Executors.newSingleThreadExecutor();
private Repository(Application application) {
mDatabase = MyDatabase.getInstance(application.getApplicationContext());
}
public static Repository getInstance(Application application) {
if (instance == null) {
instance = new Repository(application);
}
return instance;
}
public void insert(final MyModel model) {
mExecutor.execute(new Runnable() {
@Override
public void run() {
mDatabase.getMyModelDAO().insert(model);
}
});
}
public void update(final MyModel model) {
mExecutor.execute(new Runnable() {
@Override
public void run() {
mDatabase.getMyModelDAO().update(model);
}
});
}
public void delete(final MyModel model) {
mExecutor.execute(new Runnable() {
@Override
public void run() {
mDatabase.getMyModelDAO().delete(model);
}
});
}
}
抽象クラスでも@Dao注釈を使用できます。
@Insert insert(entities)
と、その_いAsyncTask
ジョブを実行する具象メソッドinsert(entities, callback)
を含む抽象_@Dao BaseDao
_クラスを作成し、抽象@Insert insert(entities)
on onBackground
およびコールバックonPostExecute
。FeedEntryDAO
も抽象拡張BaseDao
と_@Query
_メソッドを抽象化します。Kotlinでの結果の使用法は非常にきれいです:
_database.entityDao().insert(entities) { ids ->
// success
}
_
データが変更されたときにアプリのUIが自動的に更新されるようにするには、クエリメソッドの説明でLiveData型の戻り値を使用します。データベースが更新されると、RoomはLiveDataを更新するために必要なすべてのコードを生成します。
@Dao
interface MyDao {
@Query("SELECT first_name, last_name FROM user WHERE region IN (:regions)")
fun loadUsersFromRegionsSync(regions: List<String>): LiveData<List<User>>
}
注:バージョン1.0では、Roomはクエリでアクセスされたテーブルのリストを使用して、LiveDataのインスタンスを更新するかどうかを決定します。