LoginSignup
4
6

More than 5 years have passed since last update.

Room でも @Insert は row ID を戻り値にできる。

Posted at
1 / 15

要旨

Room(Android の SQLite のオブジェクト マッピング ライブラリ)においても、アイテム追加時には SQLite の row ID を戻り値として取得できる。

@Dao
public interface yourDao {

    @Insert
    void yourMethod1(Item item);  // 戻り値なし

    @Insert
    long yourMethod2(Item item);  // 戻り値あり
}

前提


ライブラリ Room

ドキュメント によれば

If the @Insert method receives only 1 parameter, it can return a long, which is the new rowId for the inserted item. If the parameter is an array or a collection, it should return long[] or List<Long> instead.

(なおレファレンス には現時点記載なし)


つまり @Insert を付けたメソッドは、戻り値を以下から選べる。

  • void
  • long(アイテムひとつ追加の場合)
  • long[] ないし List<Long>(複数追加の場合)

思うに以下が可能(メソッド名は自由)

@Dao
public interface yourDao {

    // ひとつ追加

    @Insert
    void yourMethod1a(Item item);  // 戻り値なし

    @Insert
    long yourMethod1b(Item item);  // 戻り値あり


    // 複数追加(パラメータが配列)

    @Insert
    void yourMethod2a(Item... items);

    @Insert
    long[] yourMethod2b(Item... items);

    @Insert
    List<Long> yourMethod2c(Item... items);


    // 複数追加(パラメータがリスト)

    @Insert
    void yourMethod3a(List<Item> list);

    @Insert
    long[] yourMethod3b(List<Item> list);

    @Insert
    List<Long> yourMethod3c(List<Item> list);

}

従来の Android API と比較

android.database.sqlite における追加メソッドは

SQLiteDatabase

long insert (String table, String nullColumnHack, ContentValues values)

SQLiteStatement

long executeInsert ()

どちらも戻り値は long で、追加された行の row ID を返すと説明されている。

row ID of the newly inserted row, or -1 if an error occurred


以降は row ID に関する補足


SQLite の "row ID ありテーブル"

Rowid Tables によれば

Most tables in a typical SQLite database schema are rowid tables.

つまり通常ならテーブルはこのタイプ


row ID とは

続けて row ID の説明あり

Rowid tables are distinguished by the fact that they all have a unique, non-NULL, signed 64-bit integer rowid that is used as the access key for the data in the underlying B-tree storage engine.


つまり SQLite の rowid テーブルの row ID は

  • 一意的
  • 符号付き64ビット整数(Java の long に相当)
  • 非 NULL(主キーにふさわしい)

主キーに NULL

他方 SQLite の CREATE TABLE によれば

According to the SQL standard, PRIMARY KEY should always imply NOT NULL. Unfortunately, due to a bug in some early versions, this is not the case in SQLite. Unless the column is an INTEGER PRIMARY KEY or the table is a WITHOUT ROWID table or the column is declared NOT NULL, SQLite allows NULL values in a PRIMARY KEY column. SQLite could be fixed to conform to the standard, but doing so might break legacy applications. Hence, it has been decided to merely document the fact that SQLite allowing NULLs in most PRIMARY KEY columns.


つまり SQLite の場合、普通の主キーであれば NULL 値も可。既存アプリとの整合を優先させるため同バグの修正が見送られたため。

ちなみに INTEGER PRIMARY KEY の場合は NULL なし。 row ID との関係は後述。


INTEGER PRIMARY KEY とは

ふたたび SQLite の CREATE TABLE によれば

..., if a rowid table has a primary key that consists of a single column and the declared type of that column is "INTEGER" in any mixture of upper and lower case, then the column becomes an alias for the rowid. Such a column is usually referred to as an "integer primary key". A PRIMARY KEY column only becomes an integer primary key if the declared type name is exactly "INTEGER".


つまり

  • rowid テーブルであり
  • その主キーがカラムひとつで
  • データ型が INTEGER であれば

そのカラムは row ID の別名となる。これを integer primary key と呼ぶ。

4
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
6