Room Persistence libの自動インクリメントとして主キーを作成する方法


192

Entity(Room Persistence lib)クラスのFoodを作成しfoodIdています。ここで、自動インクリメントとして作成します。

@Entity
class Food(var foodName: String, var foodDesc: String, var protein: Double, var carbs: Double, var fat: Double)
{
    @PrimaryKey
    var foodId: Int = 0
    var calories: Double = 0.toDouble()
}

foodId自動インクリメントフィールドを設定するにはどうすればよいですか?


4
do 0.toDouble()を使用する代わりに、0.0それをdoubleとして宣言することができます
RobCo '22年

2
Foodクラスの新しいインスタンスをどのように作成しますか?手動でIDを指定するか、空白のままにしますか?
Zookey 2017年

2
今後の読者への注意-Roomが未設定として扱うには、主キーが0でなければなりません。他のデフォルト値(-1など)を使用すると、RoomはIDを自動生成しません。
Martin Melka

回答:


370

autoGenerateプロパティを使用する必要があります

主キーの注釈は次のようになります。

@PrimaryKey(autoGenerate = true)

PrimaryKeyのリファレンス。


3
おかげで、私はautoIncrementを検索していたので、それを見つけることができませんでした。
chandil03

@MatPagの場合1つのテーブルに2つの主キー(複合主キー)が必要で、主キーの1つを自動インクリメントする必要がある場合はどうなりますか?どうすればそれを達成できますか?ここで答えてもらえますか?
Priyanka Alachiya 2017年

1
@MatPeg自分で生成したPrimaryKeyとRESTから取得したPrimaryKeyが必要な場合はどうなります@Entity( primaryKeys = arrayOf(COLUMN_ID_LOCAL,COLUMN_ID_REMOTE))か?
MURT

@murt複合主キーが必要ですが、達成したいことを実行できません。こちら
MatPag

リンクされたドキュメントの重要な部分:Insert methods treat 0 as not-set while inserting the item.
Micha

123

次の@PrimaryKey(autoGenerate = true)ように追加できます。

@Entity
data class Food(
        var foodName: String, 
        var foodDesc: String, 
        var protein: Double, 
        var carbs: Double, 
        var fat: Double
){
    @PrimaryKey(autoGenerate = true)
    var foodId: Int = 0 // or foodId: Int? = null
    var calories: Double = 0.toDouble()
}

34
foodIdnullである必要はありません(ただしnullである可能性があります)。たとえば、デフォルト値を使用することもできます。var foodId: Int = 0自動生成は適切に機能します。
ミシャウバラン2018年

8
@MichałBaran、java docから、型がプリミティブjava intまたはの場合long、0はnull可能として扱われ、型がIntegerまたはLongの場合、nullはnull可能です。プリミティブintとしてJVMでKotlinのIntときnull非許容動作するので、あなたは正しいとvar foodId: Int = 0動作しますが、var foodId: Int? = 0のIntので、動作しないのだろうか?JVMで整数として変換されます。@JMK、それを0にした場合int、前述の理由によりnull を許可しないようにする必要があります。
アランヴェローゾ2018

2
別の方法でなくても記述できますval jack = User(name = "Jack", phone= 1)。この場合、コンストラクタから0を削除できます
user7856586

1
このアプローチで私が目にする問題は、データクラスであるという点です。Foodが(スニペットのように)データクラスの場合、equals()の比較にはfoodが使用されるため、foodIdが異なる2つの食べ物は等しいと見なすことができます。名前付き引数をデフォルト値で使用すると、問題が解決します。
ソッティ

1
@AllanVelosoなぜfoodIdコンストラクタではなくボディに入れられたのか説明できますか?
Neeraj Sewani、

42

追加 @PrimaryKey(autoGenerate = true)

@Entity
public class User {

    @PrimaryKey(autoGenerate = true)
    private int id;

    @ColumnInfo(name = "full_name")
    private String name;

    @ColumnInfo(name = "phone")
    private String phone;

    public User(){
    }

    //type-1
    public User(String name, String phone) {
        this.name = name;
        this.phone = phone;
    }

    //type-2
    public User(int id, String name, String phone) {
        this.id = id;
        this.name = name;
        this.phone = phone;
    }

}

データの保存中

 //type-1
 db.userDao().InsertAll(new User(sName,sPhone)); 

 //type-2
 db.userDao().InsertAll(new User(0,sName,sPhone)); 

タイプ1

主キーの値を渡さない場合、デフォルトでは0またはnullになります。

タイプ2

置くIDのヌル又はゼロにオブジェクトを作成しながら、(私の場合のユーザオブジェクト)

フィールドタイプがlongまたはint(またはそのTypeConverterがlongまたはintに変換する)の場合、Insertメソッドはアイテムの挿入時に0を未設定として扱います。

フィールドのタイプがIntegerまたはLong(オブジェクト)の場合(またはそのTypeConverterがフィールドをIntegerまたはLongに変換する場合)、Insertメソッドは、アイテムの挿入時にnullを未設定として扱います。


1
autoGenerateに設定されている場合でも、カスタムIDをEntityに渡すことはできますか?
IgorGanapolsky

2
@Igor Ganapolskyはい、ただしエントリはそのカスタムIDで生成されます[自動インクリメントは機能しません]そして同じIDをもう一度渡すと、例外「UNIQUE制約が失敗しました」がスローされるため、常に新しいIDを渡すか、それを作成する必要があります[0またはnull]にして、自動インクリメントでこの処理を実行します。
kunal khedkar

3
自動生成したいのに、なぜユーザーにコンストラクターにIDを入れさせるのですか?
2018年

Kotlinでは、データクラスを使用して書き込む val jack = User(name = "Jack", phone= 1)ことができます。この場合、コンストラクターから0を削除できます
user7856586

@hellcast DBにクエリを実行するときにコンストラクターにIDを含めない場合(私は難しい方法を学んだように)、IDフィールドを割り当てません(コンストラクターで初期化したものだけです)。オブジェクトのフィールドにデータを入力するときに、同じコンストラクターを呼び出すと思います。
アリHirani

6
@Entity(tableName = "user")
data class User(

@PrimaryKey(autoGenerate = true)  var id: Int?,
       var name: String,
       var dob: String,
       var address: String,
       var gender: String
)
{
    constructor():this(null,
        "","","","")
}

4
このコードスニペットが解決策となる可能性がありますが、説明を含めると、投稿の品質を向上させるのに役立ちます。あなたは将来の読者のための質問に答えていることを覚えておいてください、そしてそれらの人々はあなたのコード提案の理由を知らないかもしれません。
Johan

4
「使用@PrimaryKey(autoGenerate = true)」のような多くの答えがあります-あなたの答えはこのスレッドに新しい何かを追加しますか?
barbsan

はい、追加します
-nullが

5

たとえば、users格納するエンティティがあり、フィールドが(firstname, lastname , email)あり、自動生成されたIDが必要な場合、これを行います。

@Entity(tableName = "users")
data class Users(
   @PrimaryKey(autoGenerate = true)
   val id: Long,
   val firstname: String,
   val lastname: String,
   val email: String
)

その後、Roomはidフィールドを自動生成および自動インクリメントします。


21
新しいUsersオブジェクトを作成するたびに、idフィールドを渡す必要があります。これは回避できますか?
Aditya Ladwa 2017

10
はい、@PrimaryKey(autoGenerated = true) val id: Long? = nullコンストラクタの外側、クラスの本体に配置します
Allan Veloso

1
@Magritte Careはもっとplsを詳しく説明しますか?
Ispam

2
@Ispam上記の私の回答では、クラス全体がどのようになるかを投稿しました。
Allan Veloso

2
実際には、IDとして単に0を指定できます。@PrimaryKeyオプションを設定した場合、Roomは自動的にIDを生成します。
romaneso

1

上記のコードでエンティティクラスに注釈を付けます。

Javaで

@PrimaryKey(autoGenerate = true)
private int id;

コトリンで

@PrimaryKey(autoGenerate = true)
var id: Int;

その後、Roomはidフィールドを自動生成および自動インクリメントします。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.