コンピュータクワガタ

かっぱのかっぱによるコンピュータ関連のサイトです

Androidアプリ入門 No.72 SQLiteの使用 データ登録

SQLiteの使用

データ登録

次に、先の例を変更してデータの登録を確認する。まずデータ登録用の画面のウィジェットを準備する。main.xmlは以下。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
<EditText
    android:id="@+id/searchEditText"
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:hint="検索条件"
    />
<Button
    android:id="@+id/readButton"
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="データ読み込み"
    />
<TextView
    android:id="@+id/resultTextView"
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    />
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    >
    <EditText
        android:id="@+id/nameEditText"
        android:layout_width="240dp" 
        android:layout_height="wrap_content" 
        android:hint="名前"
        />
    <EditText
        android:id="@+id/ageEditText"
        android:layout_width="80dp" 
        android:layout_height="wrap_content" 
        android:inputType="number"
        android:hint="年齢"
        />
</LinearLayout>
<Button
    android:id="@+id/insertButton"
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="データ登録"
    />
</LinearLayout>

実際の登録処理は、DbTest.javaを以下のようにする。

package sample.dt;

import android.app.Activity;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

public class DbTest extends Activity {
    private EditText searchEditText;
    private Button readButton;
    private TextView resultTextView;

    private EditText nameEditText;
    private EditText ageEditText;
    private Button insertButton;

    private DatabaseHelper databaseHelper;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        // DB作成
        databaseHelper = new DatabaseHelper(getApplicationContext());

        searchEditText = (EditText) findViewById(R.id.searchEditText);
        readButton = (Button) findViewById(R.id.readButton);
        readButton.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                read();
            }
        });
        resultTextView = (TextView) findViewById(R.id.resultTextView);

        nameEditText = (EditText) findViewById(R.id.nameEditText);
        ageEditText = (EditText) findViewById(R.id.ageEditText);
        insertButton = (Button) findViewById(R.id.insertButton);
        insertButton.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                insert();
            }
        });
    }

    private void read() {
        String search = searchEditText.getText().toString();
        if (search.equals("")) {
            Toast.makeText(getApplicationContext(), "検索条件を入力してください。",
                Toast.LENGTH_SHORT).show();
            return;
        }

        SQLiteDatabase db = databaseHelper.getReadableDatabase();
        Cursor cursor = db.query("emp", new String[] { "name", "age" },
                "name LIKE '%' || ? || '%'", new String[] { search }, null, null, "age DESC");
        cursor.moveToFirst();
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < cursor.getCount(); i++) {
            sb.append(cursor.getString(0)).append(",");
            sb.append(cursor.getInt(1)).append("\n");
            cursor.moveToNext();
        }
        cursor.close();
        resultTextView.setText(sb.toString());
    }

    private void insert() {
        String name = nameEditText.getText().toString();
        if (name.equals("")) {
            Toast.makeText(getApplicationContext(), "登録条件(名前)を入力してください。",
                Toast.LENGTH_SHORT).show();
            return;
        }

        String age = ageEditText.getText().toString();
        if (age.equals("")) {
            Toast.makeText(getApplicationContext(), "登録条件(年齢)を入力してください。",
                Toast.LENGTH_SHORT).show();
            return;
        }

        SQLiteDatabase db = databaseHelper.getWritableDatabase();
        db.execSQL("INSERT INTO emp(name, age) VALUES('" + name + "'," + age + ")");
        nameEditText.setText("");
        ageEditText.setText("");
        Toast.makeText(getApplicationContext(), "データを登録しました。",
            Toast.LENGTH_SHORT).show();
    }
}

実行結果は以下。簡単に解説すると、「名前」「年齢」フィールドに値を入力して、「データ登録」ボタンを押すとデータが登録される。キー項目は自動生成なのでキーの重複等はない。「名前」「年齢」フィールドは入力されているかのチェックがされている。また、年齢は数値のみ入力可能になっているため、不正な入力はできない。

今回は、SQLiteDatabase#insertメソッドではなく、あえてexecSQLメソッドを使用している。SQLiteDatabase#execSQLの定義は先に示した通りで、単純に引数のSQLを実行するだけである。特にcommit処理を行わなくても自動でcommitされる。また、本来はexecSQLでユーザー入力を元にしたSQLを発行すべきではない。それは、不正な入力によりSQLインジェクションの恐れがあるためである。わかりやすい例で、名前に「'」と入力するとプログラムを停止させることができる(この場合には実害はほとんどないが)。