Android Studioを用いてアプリ開発の勉強をしている学生です。
使用言語はKotolinです。
以下にコード一式(MainActivity.kt, DatabaseHelper.kt, activity_main.xml, strings.xmlの順)を添付しております。
SQLiteを用いてデータベースから特定の行・特定の列の値を表示させるコードの記述がMainActivity.ktのListItemClickListenerクラスのonItemClickメソッド内にあります。
ここではrawQueryメソッドでCursorオブジェクトを取得していますが、そのCursorオブジェクトについて質問があります。
質問1.
SQLiteのSELECTにおいて、WHERE句の条件式で_idを指定し、その一行だけをCursorオブジェクトとして表示しているはずなのにその後while文でCursor内を一行ずつループさせてデータを取得しようとしている理由が分かりません。
そもそも私のCursorに対する認識が間違っているのでしょうか。
質問2.
Cursorオブジェクトの0行目というのは、カラム名がある行(今回でいえば _id, name, note が書いてある一番上の行)を指しているのでしょうか。
Kotolin
1package com.websarva.wings.android.databesesample 2 3import androidx.appcompat.app.AppCompatActivity 4import android.os.Bundle 5import android.view.View 6import android.widget.* 7 8class MainActivity : AppCompatActivity() { 9 //カクテルリストビューのインデックス番号とカクテル名の初期化 10 private var _cocktailId = -1 11 private var _cocktailName = "" 12 13 //データベースヘルパーオブジェクト生成 14 private val _helper = DatabaseHelper(this@MainActivity) 15 16 //最初に行われる処理 17 override fun onCreate(savedInstanceState: Bundle?) { 18 super.onCreate(savedInstanceState) 19 setContentView(R.layout.activity_main) 20 21 //カクテルリストビューにリスナクラスを設定 22 val lvCocktail = findViewById<ListView>(R.id.lvCocktail) 23 lvCocktail.onItemClickListener = ListItemClickListener() 24 } 25 26 //保存ボタンがタップされた時の処理 27 fun onSaveButtonClick(view: View){ 28 //入力された感想を取得 29 val etNote = findViewById<EditText>(R.id.etNote) 30 val note = etNote.text.toString() 31 32 //データベースヘルパーオブジェクトからデータベース接続オブジェクトを取得 33 val db = _helper.writableDatabase 34 //メモデータを削除、インサートの順にSQLを実行する 35 //削除用SQL文字列を作成 36 val sqlDelete = "DELETE FROM cocktailmemos WHERE _id = ?" 37 //SQL文字列をもとにプリペアードステートメントを取得 38 var stmt = db.compileStatement(sqlDelete) 39 //変数のバインド 40 stmt.bindLong(1, _cocktailId.toLong()) 41 //削除SQLの実行 42 stmt.executeUpdateDelete() 43 //インサート用SQL文字列の生成 44 val sqlInsert = "INSERT INTO cocktailmemos(_id, name, note) VALUES (?, ?, ?)" 45 //SQL文字列をもとにプリペアードステートメントを取得 46 stmt = db.compileStatement(sqlInsert) 47 //変数のバインド 48 stmt.bindLong(1, _cocktailId.toLong()) 49 stmt.bindString(2, _cocktailName) 50 stmt.bindString(3, note) 51 //インサートSQLの実行 52 stmt.executeInsert() 53 54 55 //感想欄の入力欄を消去 56 etNote.setText("") 57 58 val tvCocktailName = findViewById<TextView>(R.id.tvCocktailName) 59 tvCocktailName.text = getString(R.string.tv_name) 60 61 val btnSave = findViewById<Button>(R.id.btnSave) 62 btnSave.isEnabled = false 63 } 64 65 //カクテル名がタップされた時のリスナクラス 66 private inner class ListItemClickListener: AdapterView.OnItemClickListener{ 67 override fun onItemClick(parent: AdapterView<*>, view: View, position: Int, id: Long) { 68 //カクテルリストビューのインデックス番号とカクテル名を取得 69 _cocktailId = position 70 _cocktailName = parent.getItemAtPosition(position) as String 71 72 //カクテル名表示欄にタップされたカクテル名を代入 73 val tvCocktailName = findViewById<TextView>(R.id.tvCocktailName) 74 tvCocktailName.text = _cocktailName 75 76 //保存ボタンをタップ可能にする処理 77 val btnSave = findViewById<Button>(R.id.btnSave) 78 btnSave.isEnabled = true 79 80 //カクテルリストをタップした時にすでにデータが存在した場合には、その内容を表示する 81 //データベースヘルパーオブジェクトからデータベース接続オブジェクトを取得 82 val db = _helper.writableDatabase 83 //主キーによる検索SQL文字列の用意 84 val sql = "SELECT * FROM cocktailmemos WHERE _id = ${_cocktailId}" 85 //SQLの実行 86 val cursor = db.rawQuery(sql, null) 87 //データベースから取得した値を格納するための変数の用意 88 var note = "" 89 //SQL実行の戻り値であるカーソルオブジェクトをループさせてデータベース内のデータを取得 90 while(cursor.moveToNext()){ 91 //カラムのインデックス値を取得 92 val idxNote = cursor.getColumnIndex("note") 93 //カラムのインデックス値をもとに実際のデータを取得 94 note = cursor.getString(idxNote) 95 96 } 97 //感想のEditTextの画面部品を取得しデータベースの値を反映 98 val etNote = findViewById<EditText>(R.id.etNote) 99 etNote.setText(note) 100 } 101 } 102 103 //データベースヘルパークラスの解放 104 override fun onDestroy() { 105 _helper.close() 106 super.onDestroy() 107 } 108} 109
Kotolin
1package com.websarva.wings.android.databesesample 2 3import android.content.Context 4import android.database.sqlite.SQLiteDatabase 5import android.database.sqlite.SQLiteOpenHelper 6 7class DatabaseHelper(context: Context): SQLiteOpenHelper(context, DATABASE_NAME, null, DATEBASE_VERSION) { 8 9 companion object{ 10 private const val DATABASE_NAME = "cocktailmemo.db" 11 private const val DATEBASE_VERSION = 1 12 } 13 14 override fun onCreate(db: SQLiteDatabase) { 15 //テーブル作成用SQL文字列の生成 16 val sb = StringBuilder() 17 sb.append("CREATE TABLE cocktailmemos (") 18 sb.append("_id INTEGER PRIMARY KEY,") 19 sb.append("name TEXT,") 20 sb.append("note TEXT") 21 sb.append(");") 22 val sql = sb.toString() 23 24 //SQLの実行 25 db.execSQL(sql) 26 } 27 28 override fun onUpgrade(db: SQLiteDatabase?, oldVersion: Int, newVersion: Int) { 29 } 30}
xml
1<?xml version="1.0" encoding="utf-8"?> 2<LinearLayout 3 xmlns:android ="http://schemas.android.com/apk/res/android" 4 android:layout_width="match_parent" 5 android:layout_height="match_parent" 6 android:orientation="vertical"> 7 8 <ListView 9 android:id="@+id/lvCocktail" 10 android:layout_width="match_parent" 11 android:layout_height="0dp" 12 android:layout_marginBottom="10dp" 13 android:layout_weight="0.6" 14 android:entries="@array/lv_cocktaillist"/> 15 16 <TextView 17 android:layout_width="wrap_content" 18 android:layout_height="wrap_content" 19 android:text="@string/tv_lb_name" 20 android:textSize="20sp"/> 21 22 <TextView 23 android:id="@+id/tvCocktailName" 24 android:layout_width="wrap_content" 25 android:layout_height="wrap_content" 26 android:text="@string/tv_name" 27 android:textSize="20sp"/> 28 29 <TextView 30 android:layout_width="wrap_content" 31 android:layout_height="wrap_content" 32 android:layout_marginTop="5dp" 33 android:text="@string/tv_lb_note" 34 android:textSize="20sp"/> 35 36 <EditText 37 android:id="@+id/etNote" 38 android:layout_width="match_parent" 39 android:layout_height="0dp" 40 android:layout_weight="0.4" 41 android:gravity="top" 42 android:inputType="textMultiLine"/> 43 44 <Button 45 android:id="@+id/btnSave" 46 android:layout_width="match_parent" 47 android:layout_height="wrap_content" 48 android:enabled="false" 49 android:onClick="onSaveButtonClick" 50 android:text="@string/btn_save" /> 51</LinearLayout>
XML
1<resources> 2 <string name="app_name">データベースサンプル</string> 3 <string-array name="lv_cocktaillist"> 4 <item>ホワイトレディ</item> 5 <item>バラライカ</item> 6 <item>XYZ</item> 7 <item>ニューヨーク</item> 8 <item>マンハッタン</item> 9 <item>ミシシッピミュール</item> 10 <item>ブルーハワイ</item> 11 </string-array> 12 <string name="tv_lb_name">選択されたカクテル</string> 13 <string name="tv_name">未選択</string> 14 <string name="tv_lb_note">感想</string> 15 <string name="btn_save">保存</string> 16</resources> 17
回答1件
あなたの回答
tips
プレビュー