■ はじめに
* Android の 標準データベースである、SQLiteを学ぶ。 * Realm については、以下の関連記事を参照のこと。
DB を使用する ~ Realm 編 ~
https://dk521123.hatenablog.com/entry/2018/09/01/213649
■ Android のDBについて
* Android の データベースは、SQLiteを標準サポート
SQLiteを使うには...
色々な方法があると思うが、今回は、以下の2つの方法について扱う 【1】SQLiteOpenHelper を使用する
Anko について
* Kotlinライブラリ Anko を利用する方法もあるが、 Anko が非推奨になっている...
https://github.com/Kotlin/anko/blob/master/GOODBYE.md
■ ポイント
SELECT文
Cursor cursor = db.query(DB_TABLE, cols, selection, selectionArgs, groupBy, having, orderBy); 第1引数 : テーブル名 第2引数 : 取得するテーブルの列を、文字列配列 第3引数 : where条件 第4引数 : where条件には、パラメータ?を使う事ができ、パラメータ値を文字列配列 第5引数 : GROUP BY 第6引数 : HAVING 第7引数 : ORDER BY
■ サンプル
Java
レイアウト(画面)
ID [__________(入力)__________] Name [__________(入力)__________] [ SELECT ] [ DELETE ] [ INSERT ] [ UPDATE ] [ (出力) ]
レイアウト : activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity"> <TableLayout android:layout_width="match_parent" android:layout_height="match_parent"> <TableRow android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="ID" android:id="@+id/idTextView" /> <EditText android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/idEditText" /> </TableRow> <TableRow android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Name" android:id="@+id/nameTextView" /> <EditText android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/nameEditText" /> </TableRow> <TableRow android:layout_width="match_parent" android:layout_height="match_parent"> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Select" android:id="@+id/selectButton" android:onClick="selectButtonOnClick" /> <Button style="?android:attr/buttonStyleSmall" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Delete" android:id="@+id/deleteButton" android:onClick="deleteButtonOnClick" /> </TableRow> <TableRow android:layout_width="match_parent" android:layout_height="match_parent"> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Insert" android:id="@+id/insertButton" android:onClick="insertButtonOnClick" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Update" android:id="@+id/updateButton" android:onClick="updateButtonOnClick" /> </TableRow> <TableRow android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Result" android:id="@+id/resultTextView" /> </TableRow> </TableLayout> </RelativeLayout>
画面制御 : MainActivity.java
import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.EditText; import android.widget.TextView; import java.util.Map; public class MainActivity extends AppCompatActivity { private SampleSQLiteOpenHelper dbHelper; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); this.dbHelper = new SampleSQLiteOpenHelper(super.getApplicationContext()); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.menu_main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); //noinspection SimplifiableIfStatement if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); } public void selectButtonOnClick(View view) { String id = this.getId(); String name = this.getName(); Map<String, String> results = this.dbHelper.getSqlData(id, name); String output = ""; for(Map.Entry<String, String> result : results.entrySet()) { output = output + "ID : " + result.getKey() + " / Name : " + result.getValue(); } this.setResult(output); } public void insertButtonOnClick(View view) { String id = this.getId(); String name = this.getName(); boolean isSuccessful = this.dbHelper.insert(id, name); if (isSuccessful) { this.setResult("Successful"); } else { this.setResult("Failed..."); } } public void updateButtonOnClick(View view) { String id = this.getId(); String name = this.getName(); boolean isSuccessful = this.dbHelper.updateById(id, name); if (isSuccessful) { this.setResult("Successful"); } else { this.setResult("Failed..."); } } public void deleteButtonOnClick(View view) { String id = this.getId(); String name = this.getName(); boolean isSuccessful = this.dbHelper.deleteById(id, name); if (isSuccessful) { this.setResult("Successful"); } else { this.setResult("Failed..."); } } private String getId() { return ((EditText)super.findViewById(R.id.idEditText)).getText().toString(); } private String getName() { return ((EditText)super.findViewById(R.id.nameEditText)).getText().toString(); } private void setResult(String resultValue) { TextView resultTextView = (TextView)super.findViewById(R.id.resultTextView); resultTextView.setText(resultValue); } }
DB処理 : SampleSQLiteOpenHelper.java
import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import java.util.HashMap; import java.util.Map; public class SampleSQLiteOpenHelper extends SQLiteOpenHelper { private static final String DB_NAME = "sampledb"; private static final int DB_VERSION = 1; private static final String DB_TABLE = "sampletable"; private static final String CREATE_TABLE = "CREATE TABLE IF NOT EXISTS sampletable (_id TEXT PRIMARY KEY, _name TEXT);"; private static final String DROP_TABLE = "DROP TABLE IF EXISTS sampletable;"; public SampleSQLiteOpenHelper(Context context) { this(context, DB_NAME, null, DB_VERSION); } public SampleSQLiteOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) { super(context, name, factory, version); } // データベースを作成した時に呼び出されるメソッド @Override public void onCreate(SQLiteDatabase db) { db.execSQL(CREATE_TABLE); } // データベースをバージョンアップした時に呼び出されるメソッド @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { db.execSQL(DROP_TABLE); this.onCreate(db); } public Map<String, String> getSqlData(String id, String name) { Map<String, String> results = new HashMap<>(); try { SQLiteDatabase db = this.getWritableDatabase(); String[] cols = { "_id", "_name" }; String selection = null; String[] selectionArgs = null; if (!this.isNullOrEmpty(id) && !this.isNullOrEmpty(name)) { selection = "_id = ? AND _name = ?"; selectionArgs = new String[] {id, name}; } else if (!this.isNullOrEmpty(id) && this.isNullOrEmpty(name)) { selection = "_id = ?"; selectionArgs = new String[] {id}; } else if (this.isNullOrEmpty(id) && !this.isNullOrEmpty(name)) { selection = "_name = ?"; selectionArgs = new String[] {name}; } String groupBy = null; String having = null; String orderBy = null; Cursor cursor = db.query(DB_TABLE, cols, selection, selectionArgs, groupBy, having, orderBy); boolean isEnd = cursor.moveToFirst(); while (isEnd) { results.put(cursor.getString(0), cursor.getString(1)); isEnd = cursor.moveToNext(); } } catch (Exception ex) { ex.printStackTrace(); results = null; } return results; } public boolean insert(String id, String name) { boolean isSuccessful = false; try { SQLiteDatabase db = this.getWritableDatabase(); ContentValues values = new ContentValues(); values.put("_id", id); values.put("_name", name); db.insertOrThrow(DB_TABLE, null, values); isSuccessful = true; } catch (Exception ex) { ex.printStackTrace(); isSuccessful = false; } return isSuccessful; } public boolean updateById(String id, String name) { boolean isSuccessful = false; try { SQLiteDatabase db = this.getWritableDatabase(); ContentValues values = new ContentValues(); values.put("_name", name); String whereClause = null; if (!this.isNullOrEmpty(id)) { whereClause = "_id = " + id; } db.update(DB_TABLE, values, whereClause, null); isSuccessful = true; } catch (Exception ex) { ex.printStackTrace(); isSuccessful = false; } return isSuccessful; } public boolean deleteById(String id, String name) { boolean isSuccessful = false; try { SQLiteDatabase db = this.getWritableDatabase(); ContentValues values = new ContentValues(); values.put("_name", name); String whereClause = null; if (!this.isNullOrEmpty(id)) { whereClause = "_id = " + id; } db.delete(DB_TABLE, whereClause, null); isSuccessful = true; } catch (Exception ex) { ex.printStackTrace(); isSuccessful = false; } return isSuccessful; } private boolean isNullOrEmpty(String value) { return value == null || value.isEmpty(); } }
参考資料
http://android.keicode.com/basics/sqlite-dataadapter.php
関連記事
DB を使用する ~ Realm 編 ~
https://dk521123.hatenablog.com/entry/2018/09/01/213649