AndroidStudio SQLiteを使う

## SQLiteを使用してデータの保存をする

Androidプラットフォーム自体にSQLiteのサポートが組み込まれており、
特に追加のインストールは不要

:::note info
SQLite
---
リレーショナルデータベース管理システム（RDBMS）

SQLiteはアプリケーションに直接組み込んで使用
アプリケーション内で直接動作し、
外部サーバーに依存することなく利用できる。

SQLiteはデータベースのすべてを1つのファイルに保存
データベースの管理はSQLiteが自動的に行い、
アプリケーションはSQLクエリを使ってデータを操作する
:::

### クラスを作る
~~~java:DatabaseHelperっていうクラス名で作成
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public class DatabaseHelper extends SQLiteOpenHelper {
    private static final String DATABASE_NAME = "test.db";
    private static final int DATABASE_VERSION = 1;

    public DatabaseHelper(Context context){
        super(context,DATABASE_NAME,null,DATABASE_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db){
        StringBuilder sb = new StringBuilder();
        sb.append("CREATE TABLE test (");
        sb.append("_id INTEGER PRIMARY KEY AUTOINCREMENT,");
        sb.append("name TEXT");
        sb.append(");");
        String sql = sb.toString();
        db.execSQL(sql);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion){}
}
~~~
:::note info
インポート
---
~~~java
//SQLiteOpenHelperを継承(extends)するので必要になる
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
~~~

ファイル名とバージョン
---
~~~java
//コンストラクタ呼び出し時とかに使う
private static final String DATABASE_NAME = "test.db";
private static final int DATABASE_VERSION = 1;
~~~

親クラスのコンストラクタを呼び出す
---
~~~java
public DatabaseHelper(Context context) {
    super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
/*
引数
第１ コンテキスト（通常は Activity や Application）
　　 MaineActivityでnewした時のコンストラクタの引数
第２ データベースの名前
第３ 通常は null で問題ない
第４ データベースのバージョン
　　 テーブルの変更とかした際は数値を上げる
*/
~~~

テーブル作成
---
~~~java
@Override
public void onCreate(SQLiteDatabase db){
    //StringBuilder を使って SQL 文を組み立て
    StringBuilder sb = new StringBuilder();
    sb.append("CREATE TABLE test (");
    sb.append("_id INTEGER PRIMARY KEY AUTOINCREMENT,");
    sb.append("name TEXT");
    sb.append(");");

    //文字列変換
    String sql = sb.toString();
    //作成
    db.execSQL(sql);
}
~~~

### SQL文について
~~~java:javaでのSQL文作成
    StringBuilder sb = new StringBuilder();
    sb.append("CREATE TABLE test (");
    sb.append("_id INTEGER PRIMARY KEY AUTOINCREMENT,");
    sb.append("name TEXT");
    sb.append(");");
~~~

~~~sql:この時のSQL文の内容
CREATE TABLE test (
    _id INTEGER PRIMARY KEY AUTOINCREMENT,
    name TEXT
);
~~~

アップグレード
---
~~~java
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion){}
~~~
テーブルの変更やデータ型の変更を行い
バージョンが変更される場合に実装する必要がある
:::
## MaineActivityへ記述
~~~java
public class MainActivity extends AppCompatActivity {
    //先にフィールドへクラス変数の宣言を行う
    private DatabaseHelper _helper;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    //クラスをnewしてコンストラクタに自身を渡す
        _helper = new DatabaseHelper(MainActivity.this);
    }
}
~~~

## 行った処理に応じて処理を行う
### データを追加

~~~java:データの追加
//データベース接続オブジェクトの取得
SQLiteDatabase db = _helper.getWritableDatabase();
//SQL文を用意
String sql = "INSERT INTO test (_id,name) VALUES (?,?)"
//VALUES (?,?)　へデータを入れるための準備
stmt = db.compileStatement(sql);
//バインド(？へ値を入れる)
//左に入る数値は VALUES(?,?) の左からn番目の？の位置
//右に入るのは入れたい値や文字列bind〇〇の部分で型指定
//型はCREATE TABLE時の型と合わせること
stmt.bindLong(1,数値);
stmt.bindString(2,文字列);
//SQLの実行
stmt.executeInsert();
~~~
これで追加される

### データの引き出し
~~~java:データ引き出し ⇒ 引き出した内容をLogへ
// データベース接続オブジェクトの取得
SQLiteDatabase db = _helper.getReadableDatabase();
// SQL文を用意（全ての行を取得）
String sql = "SELECT _id, name FROM test";
// クエリ実行し、結果をCursorに格納
Cursor cursor = db.rawQuery(sql, null);
// カーソルがデータを持っているか確認
if (cursor != null && cursor.moveToFirst()) {
    // 各カラムのデータを取得
    do {
        // _idカラムの値を取得（数値の場合）
        long id = cursor.getLong(cursor.getColumnIndex("_id"));
        // nameカラムの値を取得（文字列の場合）
        String name = cursor.getString(cursor.getColumnIndex("name"));
        // 取得したデータを使用（例えば表示）
        Log.d("Database", "ID: " + id + ", Name: " + name);
        
    } while (cursor.moveToNext()); // 次のレコードに進む
}

// 使用が終わったらカーソルを閉じる
cursor.close();
~~~

SQL文はたくさんあるので覚える必要がある