Cara membuat kunci utama sebagai peningkatan otomatis untuk Room Persistence lib


196

Saya membuat Makanan kelas Entity (Room Persistence lib), di mana saya ingin menjadikan foodIdsebagai peningkatan otomatis.

@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()
}

Bagaimana cara saya menyetel foodIdbidang peningkatan otomatis?


4
Alih-alih 0.toDouble()Anda dapat menggunakannya, 0.0nyatakan sebagai ganda
RobCo

2
Bagaimana Anda membuat instance baru dari kelas Makanan? Apakah Anda menentukan ID secara manual atau membiarkannya kosong?
Zookey

3
Catatan untuk pembaca di masa mendatang - kunci utama harus 0 untuk Kamar untuk memperlakukannya sebagai tidak disetel. Jika Anda menggunakan nilai default lainnya (mis. -1), Kamar tidak akan membuat otomatis id.
Martin Melka

Jawaban:


375

Anda perlu menggunakan autoGenerateproperti

Anotasi kunci utama Anda harus seperti ini:

@PrimaryKey(autoGenerate = true)

Referensi untuk PrimaryKey .


3
Terima kasih, saya sedang mencari AutoIncrement, itulah sebabnya saya tidak dapat menemukannya.
chandil03

Hey @MatPag bagaimana jika saya ingin dua kunci Primer dalam satu tabel (kunci primer Komposit) dan salah satu kunci primer harus ditambahkan otomatis? Bagaimana saya bisa mencapainya? Bisakah Anda menjawabnya di sini ?
Priyanka Alachiya

1
@ MatPeg Bagaimana jika saya ingin memiliki satu PrimaryKey yang dihasilkan sendiri, dan yang berasal dari REST @Entity( primaryKeys = arrayOf(COLUMN_ID_LOCAL,COLUMN_ID_REMOTE))?
murt

@murt Anda memerlukan kunci primer gabungan, tetapi Anda tidak dapat melakukan apa yang ingin Anda capai. Baca di sini
MatPag

Bagian penting dari dokumentasi yang ditautkan:Insert methods treat 0 as not-set while inserting the item.
Micha

127

Anda dapat menambahkan @PrimaryKey(autoGenerate = true)seperti ini:

@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()
}

35
foodIdtidak perlu nol (tetapi bisa juga). Kita juga bisa menggunakan nilai default misalnya. var foodId: Int = 0dan autogenerate akan bekerja dengan baik.
Michał Baran

8
@ MichałBaran, dari java doc, ketika jenisnya adalah java primitif intatau long, 0 diperlakukan sebagai null-mampu, ketika jenisnya adalah Integer atau Long, null adalah nullable. Karena Kotlin Int ketika non-nullable bekerja di JVM sebagai primitive int, maka Anda benar dan var foodId: Int = 0akan bekerja, tetapi var foodId: Int? = 0tidak akan bekerja sejak Int? dikonversi dalam JVM sebagai Integer. @ JMK, jika Anda membuatnya 0, Anda HARUS membuat yang tidak dapat dibatalkan intkarena alasan tersebut.
Allan Veloso

3
Anda dapat menulis tanpa dengan cara lain: val jack = User(name = "Jack", phone= 1)Dalam hal ini Anda dapat menghapus 0 dari konstruktor
user7856586

2
@ AllanVeloso Bisakah Anda menjelaskan mengapa foodIddimasukkan ke dalam tubuh dan bukan di konstruktor?
Neeraj Sewani

2
@ neer17 karena foodId akan diautogasi secara otomatis oleh Room pada saat penyisipan, kemungkinan besar tidak akan ada gunanya memilikinya di dalam konstruktor.
Allan Veloso

42

Menambahkan @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;
    }

}

saat menyimpan data

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

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

tipe 1

Jika Anda tidak memberikan nilai untuk kunci utama, secara default akan bernilai 0 atau nol.

tipe-2

Masukkan nol atau nol untuk id saat membuat objek (objek pengguna kasus saya)

Jika jenis bidangnya panjang atau int (atau TypeConverter mengubahnya menjadi panjang atau int), metode Insert memperlakukan 0 sebagai tidak disetel saat memasukkan item.

Jika tipe bidangnya adalah Integer atau Panjang (Objek) (atau TypeConverter yang mengubahnya menjadi Integer atau Panjang), metode Sisipkan memperlakukan null sebagai tidak disetel saat memasukkan item.


1
Bisakah kita meneruskan id khusus ke Entity, meskipun disetel ke autoGenerate?
IgorGanapolsky

2
@Igor Ganapolsky Ya, tetapi entri akan genrate dengan id khusus itu [kenaikan otomatis tidak akan berfungsi] Dan jika Anda lulus id yang sama lagi itu akan membuang pengecualian 'kendala UNIQUE gagal' sehingga Anda harus selalu melewati id baru atau membuatnya [0 atau null] dan biarkan peningkatan otomatis berfungsi untuk Anda.
kunal khedkar

3
Mengapa Anda bahkan membiarkan pengguna memasukkan id ke dalam konstruktor jika Anda ingin membuat autogenerasi?
hellcast

Di Kotlin Anda dapat menggunakan kelas data dan menulis: val jack = User(name = "Jack", phone= 1)Dalam hal ini Anda dapat menghapus 0 dari konstruktor
user7856586

@hellcast Jika Anda tidak memasukkan id dalam konstruktor (karena saya baru belajar dengan cara yang sulit) ketika Anda meminta DB, ia tidak akan menetapkan bidang id (itu hanya akan menjadi apa pun yang Anda inisialisasi dengan konstruktor) karena Saya menganggap itu memanggil konstruktor yang sama ketika mengisi bidang objek.
Ali 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
Sementara cuplikan kode ini mungkin solusinya, termasuk penjelasan sangat membantu untuk meningkatkan kualitas posting Anda. Ingatlah bahwa Anda menjawab pertanyaan untuk pembaca di masa depan, dan orang-orang itu mungkin tidak tahu alasan untuk saran kode Anda.
Johan

4
Ada banyak jawaban seperti "gunakan @PrimaryKey(autoGenerate = true)" - apakah jawaban Anda menambahkan sesuatu yang baru di utas ini?
barbsan

ya itu menambahkan - ini menyajikan bagaimana null mencakup bidang yang
diautogenkan secara

5

Misalnya, jika Anda memiliki usersentitas yang ingin Anda simpan, dengan bidang (firstname, lastname , email)dan Anda ingin id yang dibuat otomatis, lakukan ini.

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

Kamar kemudian akan membuat otomatis dan meningkatkan idbidang.


22
Setiap kali kita membuat objek Pengguna baru, kita harus melewati bidang id. Bisakah ini dihindari?
Aditya Ladwa

11
Ya, letakkan di @PrimaryKey(autoGenerated = true) val id: Long? = nullluar konstruktor, di badan kelas
Allan Veloso

1
@Magritte Peduli untuk menguraikan lebih banyak pls?
Ispam

2
@Ispam Dalam jawaban saya di atas saya memposting bagaimana seharusnya kelengkapan kelas.
Allan Veloso

3
Sebenarnya, Anda cukup memasukkan 0 sebagai ID. Room akan secara otomatis menghasilkan ID jika Anda telah mengatur opsi @PrimaryKey.
romaneso

1

Beri anotasi kelas Entity Anda dengan kode di atas.

Di jawa

@PrimaryKey(autoGenerate = true)
private int id;

Di Kotlin

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

Room kemudian akan membuat otomatis dan meningkatkan bidang id.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.