vaguely

和歌山に戻りました。ふらふらと色々なものに手を出す毎日。

Androidでテキストエディタ その4

前回の続きで、保存ボタンが押された後、DB(SQLite)にEditTextの文字列が保存できるようにします。

DBを作成する

Androidでは(だけじゃないかもしれませんが)DBはあらかじめテーブルなど作成済みのものを使うのではなく、初回起動の時に新規作成することが多いようです。

DataAccesser.java

import android.content.Context;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public class DataAccesser extends SQLiteOpenHelper{
    public DataAccesser(Context context) {
        super(context, "notenotenote.db", null, 1);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL("CREATE TABLE IF NOT EXISTS MyNotes ( "
                + " NoteID INTEGER PRIMARY KEY AUTOINCREMENT,"
                + " Note TEXT,"
                + " LastUpdateDate DATETIME)");
    }

DBファイルの作成は"DataAccesser(Context context)"で行っています。

またテーブルの作成は、このクラス(DataAccesser)を初期化した時に実行されるonCreateで行います。

  • SQL文を実行しているexecSQLは、Insert文やUpdate文でも使用可能なようですが、戻り値がないので実行結果の戻り値が欲しい場合は向かないようです。
  • カラムに"PRIMARY KEY AUTOINCREMENT"を指定することで、データを追加するときに自動で番号を割り当ててくれるのですが、型はIntegerである必要があります。

DBにデータを追加する

データを新規で追加できるようにします。

テーブルの作成ではSQL文をほぼそのまま書きましたが、SQLiteOpenHelperを使う場合、InsertやUpdateは形式が変わります。

DataAccesser.java

public long insertNewNote(SQLiteDatabase db, String strNewNote){

    db.beginTransaction();
    long lngResult = -1;
    ContentValues _ctvContents = new ContentValues();

    try{
        _ctvContents.put("Note", strNewNote);
        _ctvContents.put("LastUpdateDate" , java.lang.System.currentTimeMillis());
        lngResult = db.insert("MyNotes", null, _ctvContents);
        db.setTransactionSuccessful();
    }finally{
        db.endTransaction();
        return lngResult;
    }
}

  • "insert"の1つ目の引数でテーブル名を指定します。

  • ContentValuesのオブジェクトを作成して、Insertしたいデータをそこに追加します。そしてContentValuesを"insert"の3つ目の引数で渡します。

  • "NoteID"はテーブル作成の通り、自動で値を入力してくれるため何もしていません。
  • "LastUpdateDate"はDate型が入れられなかったのと、データのソートをかけたかっただけなのでcurrentTimeMillisを入れています。
  • beginTransactionでトランザクションを開始、Insertに成功したらsetTransactionSuccessfulを実行、最後にendTransactionでトランザクションを終了しています。

DataAccesserを呼び出す

EditViewActivity.java

private void saveNote(){
    DataAccesser _datAccesser = new DataAccesser(this);
    SQLiteDatabase _sqlDb = _datAccesser.getWritableDatabase();

    _ssbEditedNote = (SpannableStringBuilder)_etxEditedNote.getText();

    long lngResult = -1;

    lngResult = _datAccesser.insertNewNote(_sqlDb, _ssbEditedNote.toString());

    _sqlDb.close();

  • "getWritableDatabase"で、DataAccesserで作成したデータベースを取得します。
  • 処理が終わったら"close"して、データベースを閉じます(SQL文を複数発行したときにエラーが表示されます)。

DBのデータを更新する

既存データの更新も、Insert文とほぼ同様ですね。

DataAccesser.java

public long updateNote(SQLiteDatabase db, int intNoteId, String strEditedNote){
    db.beginTransaction();
    long lngResult = -1;
    ContentValues _ctvContents = new ContentValues();

    try{
        _ctvContents.put("Note", strEditedNote);
        _ctvContents.put("LastUpdateDate", java.lang.System.currentTimeMillis());

        lngResult = db.update("MyNotes", _ctvContents, "NoteID = ?", new String[]{"" + intNoteId});
        db.setTransactionSuccessful();
    }finally{
        db.endTransaction();
        return lngResult;
    }
}

  • "update"の3つ目の引数で条件を指定し、4つ目の引数で代入するデータ(今回はNoteID)を指定しています。

DBを検索する

既存データを全件検索してみます。

DataAccesser.java

public Cursor prepareExistingNote(SQLiteDatabase db){
    return db.query("MyNotes", null, null, null, null, null, "LastUpdateDate desc", null);
}

  • "query"の1つ目の引数でテーブル名を指定、3つ目の引数で検索条件の指定などはInsert、Updateと同じです。
  • 7つ目の引数で、ソート条件を指定しています。
  • 戻り値の型はCursorなので、そのままこのメソッドの戻り値としています。

検索したデータの取得

MainViewActivity.java

private void prepareNoteData(){
    DataAccesser _datAccesser = new DataAccesser(this);
    SQLiteDatabase sqlDb = _datAccesser.getWritableDatabase();
    Cursor csrNote = _datAccesser.prepareExistingNote(sqlDb);

    int intNoteCount = csrNote.getCount();

    int intNoteId = csrNote.getInt(csrNote.getColumnIndex("NoteID"));

    sqlDb.close();

  • Cursor型として返された結果からデータを取り出します。

  • "getCount"で結果の(列)数を取得します。

  • "getColumnIndex(カラム名)"で指定したカラムの番号を取得します。

  • "getInt(カラム番号)"で、指定したカラム番号の値(Int型)を取得します。

  • "getString(カラム番号)"で、String型を取得することもできます。

[参考]

[参考書籍]