Skip to content

Most visited

Recently visited

navigation

SQL データベースにデータを保存する

データベースへのデータ保存は、連絡先情報などの繰り返し使用する、または構造化されたデータに最適です。 このクラスでは、受講者が全般的な SQL データベースの知識に精通していることを前提としており、Android 上での SQLite データベースの導入を支援します。 Android 上でのデータベース使用の際に必要な API は、android.database.sqlite パッケージに含まれています。

スキーマとコントラクトを定義する

SQL データベースの重要な要素の 1 つがスキーマであり、これはデータベースの編成方法に関する正式な宣言です。 スキーマは、データベースを作成するために使用する SQL 文に反映されます。 コントラクト クラスとして知られているコンパニオン クラスの作成が有用です。コンパニオン クラスでは、スキーマのレイアウトを明示的に、そして体系的な自己文書化する方法で指定します。

コントラクト クラスは、URI、表、列の名前を定義する定数のコンテナです。 コントラクト クラスを使用すると、同じパッケージ内の他のすべてのクラスで、同じ定数を使用することができます。 これにより、1 つの場所で列名を変更した場合に、それをコード全体にプロパゲートすることができます。

コントラクト クラスを編成するお勧めの方法の 1 つは、クラスのルートレベルでデータベース全体に対しグローバルな定義を設定することです。 その後、その列を列挙する各表の内部クラスを作成します。

注: BaseColumns インターフェースを実装することで、内部クラスでは、カーソル アダプタのようないくつかの Android クラスにも含まれると想定される、_ID と呼ばれるプライマリ キーフィールドを継承することができます。 これは必須ではありませんが、データベースが Android フレームワークと調和して動作する上で役立ちます。

たとえば、次のスニペットでは、単一の表の表名と列名を定義します。

public final class FeedReaderContract {
    // To prevent someone from accidentally instantiating the contract class,
    // make the constructor private.
    private FeedReaderContract() {}

    /* Inner class that defines the table contents */
    public static class FeedEntry implements BaseColumns {
        public static final String TABLE_NAME = "entry";
        public static final String COLUMN_NAME_TITLE = "title";
        public static final String COLUMN_NAME_SUBTITLE = "subtitle";
    }
}

SQL ヘルパーを使用してデータベースを作成する

データベースの概要を定義した後、データベースと表を作成、管理するメソッドを実装する必要があります。 表を作成して削除するための一般的な宣言の例を次にいくつか示します。

private static final String TEXT_TYPE = " TEXT";
private static final String COMMA_SEP = ",";
private static final String SQL_CREATE_ENTRIES =
    "CREATE TABLE " + FeedEntry.TABLE_NAME + " (" +
    FeedEntry._ID + " INTEGER PRIMARY KEY," +
    FeedEntry.COLUMN_NAME_TITLE + TEXT_TYPE + COMMA_SEP +
    FeedEntry.COLUMN_NAME_SUBTITLE + TEXT_TYPE + " )";

private static final String SQL_DELETE_ENTRIES =
    "DROP TABLE IF EXISTS " + FeedEntry.TABLE_NAME;

デバイスの内部ストレージにファイルを保存する場合と同様に、Android はアプリケーションに関連付けられているプライベート ディスク スペースにデータベースを格納します。 デフォルトでは、この領域は他のアプリケーションからアクセスできないため、データの安全性は確保されています。

有用な一連の API が SQLiteOpenHelper クラスで利用できます。このクラスを使用してデータベースへの参照を取得すると、アプリの起動時ではなく必要な場合にのみ、データベースの作成、更新などの時間がかかる可能性が高い処理が実行されます。 getWritableDatabase() またはgetReadableDatabase() の呼び出し以外は必要ありません。

注: 長時間実行する可能性があるため、AsyncTask または IntentService などを使用して、getWritableDatabase() または getReadableDatabase() をバックグラウンド スレッドで呼び出すようにしてください。

SQLiteOpenHelper を使用するには、onCreate()onUpgrade()onOpen() コールバック メソッドをオーバーライドするサブクラスを作成します。 また onDowngrade() を実装することもできますが、必須ではありません。

次に、上記に示したいくつかのコマンドを使用した SQLiteOpenHelper の実装例を示します。

public class FeedReaderDbHelper extends SQLiteOpenHelper {
    // If you change the database schema, you must increment the database version.
    public static final int DATABASE_VERSION = 1;
    public static final String DATABASE_NAME = "FeedReader.db";

    public FeedReaderDbHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(SQL_CREATE_ENTRIES);
    }
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // This database is only a cache for online data, so its upgrade policy is
        // to simply to discard the data and start over
        db.execSQL(SQL_DELETE_ENTRIES);
        onCreate(db);
    }
    public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        onUpgrade(db, oldVersion, newVersion);
    }
}

データベースにアクセスするには、SQLiteOpenHelper のサブクラスのインスタンスを作成します。

FeedReaderDbHelper mDbHelper = new FeedReaderDbHelper(getContext());

データベースに情報を格納する

ContentValues オブジェクトを insert() メソッドに渡してデータベースにデータを格納できます。

// Gets the data repository in write mode
SQLiteDatabase db = mDbHelper.getWritableDatabase();

// Create a new map of values, where column names are the keys
ContentValues values = new ContentValues();
values.put(FeedEntry.COLUMN_NAME_TITLE, title);
values.put(FeedEntry.COLUMN_NAME_SUBTITLE, subtitle);

// Insert the new row, returning the primary key value of the new row
long newRowId = db.insert(FeedEntry.TABLE_NAME, null, values);

insert() の最初の引数は単なる表の名前です。

第 2 引数で、ContentValues が空の場合(つまりいずれの値も put しなかった場合)にフレームワークが実行する内容を示します。列の名前を指定すると、フレームワークは行を挿入し、その列の値を null に設定します。 このコードサンプルのように null を指定すると、フレームワークは値がない場合には行を挿入しません。

データベースから情報を読み取る

データベースから情報を読み取るには、query() メソッドを使用して選択条件および対象となる列をこれに渡します。このメソッドは、insert()update() 要素を組み合わせたもので(列リストを除く)、挿入するデータではなく取得対象のデータを定義します。 クエリの結果は、Cursor オブジェクトとして返されます。

SQLiteDatabase db = mDbHelper.getReadableDatabase();

// Define a projection that specifies which columns from the database
// you will actually use after this query.
String[] projection = {
    FeedEntry._ID,
    FeedEntry.COLUMN_NAME_TITLE,
    FeedEntry.COLUMN_NAME_SUBTITLE
    };

// Filter results WHERE "title" = 'My Title'
String selection = FeedEntry.COLUMN_NAME_TITLE + " = ?";
String[] selectionArgs = { "My Title" };

// How you want the results sorted in the resulting Cursor
String sortOrder =
    FeedEntry.COLUMN_NAME_SUBTITLE + " DESC";

Cursor c = db.query(
    FeedEntry.TABLE_NAME,                     // The table to query
    projection,                               // The columns to return
    selection,                                // The columns for the WHERE clause
    selectionArgs,                            // The values for the WHERE clause
    null,                                     // don't group the rows
    null,                                     // don't filter by row groups
    sortOrder                                 // The sort order
    );

Cursor 内の特定の行に注目するには、いずれかの Cursor 移動メソッドを使用します。これは、必ず値の読み取りを開始する前に呼び出す必要があります。 通常、初めに moveToFirst() を呼び出します。これは、結果の最初のエントリ上に「読み取り位置」を置きます。 各行では、getString() または getLong() のような Cursor 取得メソッドのいずれかを呼び出すことによって、列の値を読み取ることができます。各取得メソッドに対して、必要な列のインデックス位置を渡す必要があります。これは、 getColumnIndex() または getColumnIndexOrThrow()を呼び出すことによって取得できます。以下に例を示します。

cursor.moveToFirst();
long itemId = cursor.getLong(
    cursor.getColumnIndexOrThrow(FeedEntry._ID)
);

データベースから情報を削除する

表から行を削除するには、削除対象の行を特定するための条件を指定する必要があります。 データベース API により、SQL インジェクションから保護される選択条件を作成するメカニズムが提供されます。 このメカニズムでは、選択の指定を選択句と選択引数に分割します。 句では参照対象の列を定義し、また、列のテストを組み合わせることができます。 引数はテスト対象の値であり、句にバインドされます。結果は通常の SQL 文と同様には扱われないため、SQL インジェクションの影響を受けません。

// Define 'where' part of query.
String selection = FeedEntry.COLUMN_NAME_TITLE + " LIKE ?";
// Specify arguments in placeholder order.
String[] selectionArgs = { "MyTitle" };
// Issue SQL statement.
db.delete(FeedEntry.TABLE_NAME, selection, selectionArgs);

データベースをアップデートする

データベースの値のサブセットを変更する必要がある場合には、update() メソッドを使用します。

表のアップデートでは、insert() のコンテンツ値の構文と、delete()where 構文が組み合わされます。

SQLiteDatabase db = mDbHelper.getReadableDatabase();

// New value for one column
ContentValues values = new ContentValues();
values.put(FeedEntry.COLUMN_NAME_TITLE, title);

// Which row to update, based on the title
String selection = FeedEntry.COLUMN_NAME_TITLE + " LIKE ?";
String[] selectionArgs = { "MyTitle" };

int count = db.update(
    FeedReaderDbHelper.FeedEntry.TABLE_NAME,
    values,
    selection,
    selectionArgs);
This site uses cookies to store your preferences for site-specific language and display options.

Get the latest Android developer news and tips that will help you find success on Google Play.

* Required Fields

Hooray!

Browse this site in ?

You requested a page in , but your language preference for this site is .

Would you like to change your language preference and browse this site in ? If you want to change your language preference later, use the language menu at the bottom of each page.

This class requires API level or higher

This doc is hidden because your selected API level for the documentation is . You can change the documentation API level with the selector above the left navigation.

For more information about specifying the API level your app requires, read Supporting Different Platform Versions.

Take a one-minute survey?
Help us improve Android tools and documentation.