データベース ビュー Room for Android
Room は、Google が AndroidX ライブラリとしてパッケージ化し、また推奨している SQLite 上の抽象化レイヤーです。 バージョン 2.1 以降、Room はストアド クエリとして知られるデータベース ビューを追加する機能を提供します。
- Database Views を使用する良い理由は次のとおりです。
- テーブルのすべてのフィールドを調べるのではなく、必要なフィールドのみをクエリできます。
このチュートリアルでは、レストランの顧客がフィードバックを残し、そのフィードバックを Room managed データベースに保存できる Customer Surveys アプリを作成します。 このプロセスでは、次のことを学習します。
- データベース ビューとは何か。
- データベース ビューの作成方法。
- SELECTクエリを簡単に書くための使用方法
このチュートリアルでは、Room でコルーチンを使用します。 詳細は、「Coroutines With Room Persistence Library」チュートリアルを参照してください。
はじめに
このチュートリアルの上部または下部にある [Download Materials] ボタンをクリックして、スターター プロジェクトをダウンロードします。
Gradleの同期が完了したら、プロジェクトの構造を確認します。 このプロジェクトは MVVM アーキテクチャに準拠しているため、類似した機能は 1 つのパッケージの下にあります。 このチュートリアルで使用します。
ビルドして実行します。 ウェルカムメッセージ、画像、START SURVEYボタンのあるシンプルな画面が表示されます。
START SURVEYボタンをタップしてください。 このチュートリアルの目的では、レストランで食事をしていないことは無視してください。 :]
次の画面は、アンケート画面です。 電子メールの入力フィールド、評価する食事を選択するラジオボタン、3つの質問があります。 各質問の下には、Good、Average、Badのボタンがあり、ユーザーが満足度を評価できます。
SUBMIT SURVEYボタンも表示されます)。 タップすると、まだアンケートに参加する時間ではありませんというトーストが表示されます。
これで、ビューレストランにようこそ!ここでは、素晴らしい自然の景色を見ながら、おいしい食事を味わい、満足度を評価することができます。 その間に、ルーム データベース ビューについても学んでください。
データベース ビューの使用
便利なようにあらかじめパッケージ化された SELECT クエリの追加機能を持つテーブルを考えてみてください。 Room バージョン 2.1 以降では、これらをデータベース ビューと呼び、同じ名前 (@DatabaseView
) のアノテーションを提供します。
このアノテーションを使用すると、クラスをマークしてデータベース ビューのように動作させることができます。 これにより、次のようにクラスにクエリをアタッチできます。
@DatabaseView("SELECT user.id, user.name " + "AS departmentName FROM user " + "WHERE user.departmentId = department.id")class User { var id: Long = 0 var name: String? = null}
その後、DAO でこのクラスを使用して、データベース内のテーブルなどのエンティティとしてマークされたクラスと同じ方法でデータにクエリを実行できます。 DAO は通常、CUD (Create, Update and Delete) メソッドを含み、データベースへの読み取りおよび書き込みアクセスに必要な他のメソッドを含むこともできます。
データベース ビューとエンティティの比較
@DatabaseView
でアノテーションされたクラスは、Entity
クラスと似ています。
Database View
s と Entity
s は両方とも @ColumnInfo
を使用でき、フィールドに関連付けられた列情報をカスタマイズできます。両者には多くの類似点がありますが、DatabaseView
と Entity
の間にも違いがあります:
-
Entity
では INSERT、UPDATE、DELETE を使用できますが、DatabaseView
では使用できません。 - アプリのビューはすべて
views
で定義しますが、エンティティはentities
で定義します。
DatabaseView
が何か、Entity
クラスとどう比較対照するかが分かったので、いよいよそれを使って、ビュー レストランのアンケートを送信してください。
アンケートの送信
最初のステップは、アンケートを送信し、[アンケートを送信] ボタンをタップした後に Room データベースに保存するためのロジックを追加することです。
// 1val email = editEmail.text.toString()// 2if (validateEmail(email)) { // 3 val meal = when (radioGroupMeals.checkedRadioButtonId) { R.id.radioBreakfast -> "Breakfast" R.id.radioLunch -> "Lunch" R.id.radioDinner -> "Dinner" else -> "No Meal" } // 4 val customerSurvey = SurveyListItem .CustomerSurvey(0, email, meal, questionOneAnswer, questionTwoAnswer, questionThreeAnswer) customerSurveyViewModel.insertCustomerSurvey(customerSurvey) // 5 findNavController() .navigate(R.id.action_surveyFragment_to_surveyCompletedFragment)}
このコードで行っていることは次のとおりです。
-
editEmail
から電子メールを取得し、変数に代入します。email
. - この条件チェックで
validateEmail(email)
を呼び出し、メールがnull
であるかどうかをチェックしています。null
の場合はfalse
を返します。 また、入力されたメールが有効かどうかもチェックし、有効でない場合はfalse
を返します。 -
validateEmail(email)
がtrue
を返したらif
文の中のコードが実行されます。meal
はラジオグループからユーザーが選択した食事の種類を保持します。 -
meal
の値を取得したら、SurveyListItem.CustomerSurvey
を作成します。 この目的のためにリスナーを持つtoggleButtonListeners()
から、questionOneAnswer
、questionTwoAnswer
、questionThreeAnswer
の値を取り出します。 - ここで、
CustomerSurveyViewModel
内のinsertCustomerSurvey(customerSurvey)
を呼び出してcustomerSurvey
を保存します。このロジックはRoomに保存するための処理です。 - SurveyCompletedFragment.
これを追加した後、customerSurveyViewModel
と findNavController()
には赤い下線があることに気がつきます。 これを修正するには、まず、CustomerSurveyViewModel
初期化をクラスの先頭、questionThreeAnswer
初期化のすぐ下に追加します。
private val customerSurveyViewModel: CustomerSurveyViewModel by viewModels()
IDEが要求したら、それぞれのimport文を追加することを確認します。
ビルドして実行します。 アンケートを開始し、必要な電子メール入力を行い、質問への回答を選択します。
素晴らしい、アンケートが完了しました。
VIEW SURVEYS ボタンをタップします… おっと、まだ何もしてくれませんね。 心配しないでください、すぐに修正されますよ。
次のセクションでは、最初の DatabaseView
を作成する方法を学びます。
データベース ビューの作成
ビューを作成するには、クラスまたはデータ クラスに @DatabaseView
アノテーションを追加します。 まず、customersurveys/SurveyListItem.kt に移動してください。
SurveyListItem
の一番下、QuestionOneSadView
のすぐ下に、次のように追加します。
data class HappyBreakFastView( override val email: String) : SurveyListItem()
このデータ クラスは SurveyListItem
から email 変数をオーバーライドし、クラスから継承します – つまり、SurveyListItem
のサブタイプであることを意味します。
このデータ クラスを作成したら、HappyBreakFastView
データ クラスのすぐ上に、食事が「朝食」に設定されている CustomerSurvey テーブルからすべてのメール ID をフェッチする SELECT クエリを持つ @DatabaseView
を追加します。 アノテーションは次のようになります。
@DatabaseView("SELECT CustomerSurvey.email FROM CustomerSurvey WHERE CustomerSurvey.meal = 'Breakfast'")
アノテーション内のクエリについて注意すべき点は次のとおりです。 この場合、電子メールだけが必要です。 5290> を使用して CustomerSurvey
.
Using Room Database Views in DAO Queries
最初に、アプリの @Database
内の views
に HappyBreakFastView
を含めます。
database/AppDatabase.kt に移動して、views
内で、SurveyListItem.HappyBreakFastView::class
を追加します。 更新された @Database
アノテーションは、次のようになります:
@Database(entities = , version = 2, exportSchema = false, views = )
Notice that the version = 2
. AppDatabase に view
を追加するたびに、データベースのバージョンを更新する必要があります – そうしないと、アプリがクラッシュします。 この場合、バージョンを 2 に更新しました。 これらの変更をすべて適用するために gradle を同期します。
次に、customers/CustomerSurveysDao.kt に移動して、getQuestionOneSadView()
直下に、次のコードを追加してください。
@Query("SELECT * FROM HappyBreakFastView")fun getHappyBreakFastCustomers():LiveData<List<SurveyListItem.HappyBreakFastView>>
このメソッドは、レストランからアンケートのいずれかの側面に満足したすべての顧客を取得します。
- 最初に、通常のクエリと同様に
HappyBreakFastView
を使用します。 - このメソッドを
CustomerSurveyRepo
で呼び出し、いずれかの質問に「良い」と回答したすべての顧客のリストを取得します。 このメソッドの戻り値の型は、観測可能な変数ホルダーであるSurveyListItem.HappyBreakFastView
型のリストLiveData
であることに注意してください。
さて、あなたは view
と CustomerSurveysDao
で肯定的に回答した顧客のリストを照会するメソッドを作成しました。 次のセクションでは、リポジトリ クラスからこのメソッドを呼び出す方法を学びます。
DatabaseViewを使用してデータを取得する
customersurveys/CustomerSurveyRepo.ktに移動して、getQuestionOneSadView()
のすぐ下に次のメソッドを追加します:
fun getHappyBreakFastCustomers() : LiveData<List<SurveyListItem.HappyBreakFastView>> { return customerSurveysDao.getHappyBreakFastCustomers()}
このメソッドはCustomerSurveysDao
からgetHappyBreakFastCustomers()
を呼び出して、Roomからデータを取得します。 その戻り値はLiveData
で、このメソッドの呼び出し元はデータの変化を観察することができます。
次に、CustomerSurveyViewModel
にgetHappyBreakFastCustomers()
への呼び出しを追加します。 これは、ビューにデータを表示する役割を果たします。この場合、ビューはDatabaseView
ではなく、AllSurveysFragmentです。
「customersurveys/CustomerSurveyViewModel.kt」に移動し、次のコードを追加します。
val happyBreakfastCustomers : LiveData<List<SurveyListItem.HappyBreakFastView>> by lazy { customerSurveyRepo.getHappyBreakFastCustomers()}
この変数は CustomerSurveyRepo
から getHappyBreakFastCustomers()
を呼び出してその値を取得します。
次に、データを表示できるように UI を更新します。
データを UI に表示する
allsurveys/AllSurveysFragment に移動します。
private fun getHappyBreakfastCustomers() { customerSurveyViewModel.happyBreakfastCustomers.observe(viewLifecycleOwner, Observer { customerSurveyList -> if (customerSurveyList.isEmpty()) { layoutEmptyView.visibility = View.VISIBLE rvReviews.visibility = View.GONE } else { layoutEmptyView.visibility = View.GONE rvReviews.visibility = View.VISIBLE initView(customerSurveyList) } })}private fun initView(customerSurveySurveyList: List<SurveyListItem.HappyBreakFastView>) { val customerSurveysAdapter = CustomerSurveysAdapter(customerSurveySurveyList) rvReviews.adapter = customerSurveysAdapter}
このコードが何を行うかを説明します。
- 最初に、
happyBreakfastCustomers
を呼び出してその値を観察します。 - 観察ラムダの内部では、customerSurveyList が
null
かどうかを確認します。 リストがnull
の場合、TextView
のNo surveys found! メッセージをvisibleに設定し、RecyclerView
を非表示にします。null
でない場合は、TextView
の可視性を GONE に設定し、RecyclerView
を表示します。 -
initView(customerSurveySurveyList: List)
はCustomerSurveysAdapter
をcustomerSurveyList
で初期化し、RecyclerView
のアダプタをCustomerSurveysAdapter
に設定して、アンケートのリストを UI に表示します。
IDE は SurveyListItem
インポートを追加するように促します。
import com.raywenderlich.android.customersurveys.customersurveys.SurveyListItem
これで UI にデータが表示されましたが、すべてが完璧に動作するまでには、あと数ステップしかありません。
次に、ユーザー インターフェイス (スピナー ウィジェット) のドロップダウンで選択されたオプションに応じて Room からデータをフェッチするコードを追加します。
異なるビューのデータをフェッチする
以下のコード部分を AllSurveysFragment.kt::
private fun spinnerListener() { filterSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener { override fun onNothingSelected(parent: AdapterView<*>?) {} override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) { when (position) { 0 -> resetState() 1 -> getAllCustomerSurveys() 2 -> getHappyBreakfastCustomers() 3 -> getSadDinnerCustomers() 4 -> getAverageLunchCustomers() 5 -> getQuestionOneSadCustomers() } } }}
上のコード部分は onItemSelectedListener
を filterSpinner
に設定し、2 つのメソッドをオーバーライドします。 onNothingSelected
と onItemSelected
です。 何も選択されていないときは何もしたくないので、onNothingSelected
は空のままです。
onItemSelected
には when
式があり、filterSpinner
で選択されたオプションに応じて異なるメソッドを呼び出します。 これらのメソッドは getHappyBreakfastCustomers()
と似ていますが、別の DatabaseView
を使用してデータをフェッチします。
最後に、次のように setupSpinner()
のすぐ後に、onViewCreated
内で spinnerListener()
への呼び出しを追加します。
Navigating to All Surveys
これは、ビューの動作を確認するために必要な最後のステップです。
completedsurvey/SurveyCompletedFragment.kt に移動して、btnViewSurveys
内のコードをアンコメントしてください。 最終結果は次のようになります。
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) btnViewSurveys.setOnClickListener { findNavController() .navigate(R.id.action_surveyCompletedFragment_to_allSurveysFragment) }}
ここでは、VIEW SURVEYS ボタンのクリック リスナーを設定し、AllSurveysFragment
に移動しています。
コードのコメントを解除すると、IDE は findNavController()
をインポートするように要求します。 必要な.
をインポートするだけで、アンケートを構築、実行、開始し、質問に回答して送信することができます。 最後に、すべてのアンケートを表示し、スピナーで選択したオプションに応じてすべてのデータを取得することができます。
Congratulations ! あなたはビューレストランでの体験を終了しました。 素晴らしい食事をし、素晴らしい景色を眺め、DatabaseViews が何であるかを学ぶ機会があったことを願っています。
ここからどこへ行くのでしょうか。
チュートリアルの上部または下部にある [Download Materials] ボタンを使用して、最終プロジェクトをダウンロードします。
Room の機能についての詳細情報は、Android からの公式ドキュメントをチェックしてください。
raywenderlich.com Weekly
The raywenderlich.com ニュースレターは、モバイル開発者として知っておくべきすべてのことについて最新情報を入手するための最も簡単な方法です。
私たちのチュートリアルやコースのダイジェストを毎週お届けし、ボーナスとして無料の詳細なメールコースをお届けします!
平均評価
4.8/5
このコンテンツに評価を付ける
Sign in to add a rating
…
Leave a Reply