วิธีการสร้างคีย์หลักเป็น autoincrement สำหรับห้องพักการคงอยู่ lib


196

ฉันกำลังสร้างอาหารคลาส Entity (Room Persistence lib) ที่ฉันต้องการทำเป็นfoodIdautoincrement

@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
แทนที่จะบอก0.toDouble()ว่าคุณสามารถใช้0.0มันเป็น Double ได้เลย
RobCo

2
คุณสร้างอินสแตนซ์ใหม่ของคลาสอาหารได้อย่างไร คุณระบุ ID ด้วยตนเองหรือไม่หรือปล่อยว่างไว้?
Zookey

3
หมายเหตุสำหรับผู้อ่านในอนาคต - คีย์หลักต้องเป็น 0 สำหรับห้องเพื่อถือว่าเป็น unset หากคุณใช้ค่าเริ่มต้นอื่น ๆ (เช่น -1) ห้องจะไม่สร้างรหัสอัตโนมัติ
Martin Melka

คำตอบ:


375

คุณต้องใช้autoGenerateทรัพย์สิน

คำอธิบายประกอบคีย์หลักของคุณควรเป็นเช่นนี้:

@PrimaryKey(autoGenerate = true)

อ้างอิงสำหรับPrimaryKey


3
ขอบคุณฉันกำลังค้นหา autoIncrement นั่นคือสาเหตุที่หาไม่พบ
chandil03

เฮ้ @MatPag จะทำอย่างไรถ้าฉันต้องการคีย์หลักสองตัวในหนึ่งตาราง (คีย์หลักแบบรวม) และหนึ่งในคีย์หลักควรเพิ่มขึ้นอัตโนมัติ ฉันจะบรรลุสิ่งนั้นได้อย่างไร คุณสามารถตอบคำถามนี้ที่นี่ ?
Priyanka Alachiya

1
@MatPeg อะไรในกรณีถ้าผมต้องการที่จะมีหนึ่ง PrimaryKey เป็นตัวเองสร้างขึ้นและคนที่มาจากส่วนที่เหลือ@Entity( primaryKeys = arrayOf(COLUMN_ID_LOCAL,COLUMN_ID_REMOTE))?
ทำลาย

@murt คุณต้องการคีย์หลักแบบรวม แต่คุณไม่สามารถทำสิ่งที่คุณต้องการได้ อ่านที่นี่
MatPag

ส่วนสำคัญของเอกสารที่เชื่อมโยง:Insert methods treat 0 as not-set while inserting the item.
Micha

127

คุณสามารถเพิ่ม@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()
}

35
foodIdไม่จำเป็นต้องเป็นโมฆะ (แต่สามารถ) หนึ่งสามารถใช้ค่าเริ่มต้นเช่น var foodId: Int = 0และ autogenerate จะทำงานอย่างถูกต้อง
Michał Baran

8
@ MichałBaranจาก java doc เมื่อชนิดเป็นจาวาดั้งเดิมintหรือlong0 ถือว่าเป็น null ได้เมื่อชนิดเป็นจำนวนเต็มหรือยาวเป็นโมฆะเป็นโมฆะ ตั้งแต่ Kotlin Int เมื่อ non-nullable ทำงานใน JVM ในฐานะ int ดั้งเดิมคุณจะถูกต้องและvar foodId: Int = 0จะทำงาน แต่var foodId: Int? = 0จะไม่ทำงานตั้งแต่ Int? ถูกแปลงเป็น JVM ในฐานะ Integer @JMK หากคุณทำให้เป็น 0 คุณต้องทำให้เป็นโมฆะไม่ได้intด้วยเหตุผลข้างต้น
อัลลัน Veloso

3
คุณสามารถเขียนได้โดยไม่ใช้วิธีอื่น: val jack = User(name = "Jack", phone= 1)ในกรณีนี้คุณสามารถลบ 0 ออกจากตัวสร้าง
7856586

2
@AllanVeloso คุณช่วยอธิบายได้ไหมว่าทำไมfoodIdถูกใส่เข้าไปในร่างกายและไม่ได้อยู่ในคอนสตรัคเตอร์?
Neeraj Sewani

2
@ neer17 เนื่องจาก foodId จะถูกสร้างอัตโนมัติโดย Room เมื่อมีการแทรกมีแนวโน้มว่าจะไม่มีประโยชน์ที่จะใช้มันใน constructor
อัลลัน Veloso

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

ใส่null หรือ zero สำหรับ idในขณะที่สร้างวัตถุ (วัตถุกรณีผู้ใช้ของฉัน)

ถ้าชนิดของเขตข้อมูลมีความยาวหรือ int (หรือ TypeConverter จะแปลงเป็นแบบยาวหรือ int) วิธีการแทรกจะถือว่า 0 เป็นค่าที่ไม่ได้ตั้งค่าขณะที่แทรกรายการ

ถ้าชนิดของเขตข้อมูลนั้นเป็นจำนวนเต็มหรือยาว (วัตถุ) (หรือประเภทของตัวแปลงจะแปลงเป็นจำนวนเต็มหรือยาว) วิธีการแทรกจะถือว่าเป็นค่าที่ไม่ได้ตั้งค่าขณะที่แทรกรายการ


1
เราสามารถส่งรหัสที่กำหนดเองไปที่เอนทิตี้แม้ว่าจะถูกตั้งเป็น autoGenerate หรือไม่
IgorGanapolsky

2
@Igor Ganapolsky ใช่ แต่รายการจะสร้างด้วยรหัสที่กำหนดเอง [การเพิ่มอัตโนมัติจะไม่ทำงาน] และถ้าคุณผ่าน ID เดียวกันอีกครั้งมันจะส่งข้อยกเว้น 'ข้อ จำกัด UNIQUE ล้มเหลว' ดังนั้นคุณต้องผ่าน ID ใหม่เสมอหรือทำให้ [0 หรือ null] และให้การเพิ่มอัตโนมัติทำงานสำหรับคุณ
kunal khedkar

3
ทำไมคุณถึงปล่อยให้ผู้ใช้ใส่รหัสในตัวสร้างหากคุณต้องการสร้างอัตโนมัติ?
hellcast

ใน Kotlin คุณสามารถใช้คลาสข้อมูลและเขียน: val jack = User(name = "Jack", phone= 1)ในกรณีนี้คุณสามารถลบ 0 ออกจากตัวสร้าง
user7856586

@hellcast หากคุณไม่ได้ใส่รหัสในตัวสร้าง (เพราะฉันเพิ่งเรียนรู้วิธีที่ยาก) เมื่อคุณค้นหา DB มันจะไม่กำหนดเขตข้อมูล id (มันจะเป็นสิ่งที่คุณเริ่มต้นด้วยในตัวสร้าง) ตั้งแต่ ฉันคิดว่ามันเรียกนวกรรมิกเดียวกันเมื่อเติมฟิลด์ของวัตถุ
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
ในขณะที่ข้อมูลโค้ดนี้อาจเป็นโซลูชันรวมถึงคำอธิบายช่วยปรับปรุงคุณภาพการโพสต์ของคุณ จำไว้ว่าคุณกำลังตอบคำถามสำหรับผู้อ่านในอนาคตและคนเหล่านั้นอาจไม่ทราบสาเหตุของการแนะนำรหัสของคุณ
Johan

4
มีคำตอบมากมายเช่น "ใช้@PrimaryKey(autoGenerate = true)" - คำตอบของคุณเพิ่มอะไรใหม่ในกระทู้นี้หรือไม่?
barbsan

ใช่มันเพิ่ม - มันแสดงให้เห็นว่า null ครอบคลุมฟิลด์ autogenearted ได้อย่างไร
Marian Paździoch

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
)

ห้องจะสร้างอัตโนมัติและเพิ่มidฟิลด์โดยอัตโนมัติ


22
ทุกครั้งที่เราสร้างวัตถุผู้ใช้ใหม่เราจะต้องผ่านเขตข้อมูล ID สามารถหลีกเลี่ยงได้ไหม
Aditya Ladwa

11
ใช่วาง@PrimaryKey(autoGenerated = true) val id: Long? = nullนอกนวกรรมิกในร่างกายของคลาส
อัลลัน Veloso

1
@Magritte สนใจที่จะบรรจงเพิ่มเติมกรุณา?
Ispam

2
@ สแปมในคำตอบของฉันด้านบนฉันโพสต์ว่าคลาสแบบสมบูรณ์ควรมีลักษณะอย่างไร
อัลลัน Veloso

3
ที่จริงแล้วคุณสามารถใส่ 0 เป็น ID ห้องจะสร้าง ID โดยอัตโนมัติหากคุณตั้งค่าตัวเลือก @PrimaryKey
romaneso

1

อธิบายคลาสเอนทิตีของคุณด้วยรหัสด้านบน

ในภาษาจาวา

@PrimaryKey(autoGenerate = true)
private int id;

ในคอตลิน

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

ห้องจะสร้างอัตโนมัติและเพิ่มฟิลด์รหัสอัตโนมัติ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.