Як зробити первинний ключ як автоматичне посилення для кімнати


196

Я створюю їжу класу Entity (Room Persistence lib), де я хочу зробити 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
Замість цього 0.toDouble()ви можете використовувати 0.0, оголосити це як подвійне
— RobCo

2
Як ви створюєте новий екземпляр класу Food? Ви вказуєте ідентифікатор вручну або залишаєте його порожнім?
— Zookey

3
Примітка для майбутніх читачів - первинний ключ повинен бути 0 для кімнати, щоб вважати це невстановленим. Якщо ви використовуєте будь-яке інше значення за замовчуванням (наприклад, -1), Room не автоматично створить ідентифікатор.
— Мартін Мелька

Відповіді:


375

Вам потрібно використовувати autoGenerateмайно

Ваша основна примітка щодо ключових слів повинна бути такою:

@PrimaryKey(autoGenerate = true)

Довідка для PrimaryKey .


3
Дякую, я шукав автоматичне збільшення, ось чому не вдалося знайти.
— chandil03

Привіт @MatPag, що робити, якщо я хочу два первинні ключі в одній таблиці (складені первинні ключі) та один із первинних ключів слід автоматично наростити? Як я можу цього досягти? Ви можете відповісти на це тут ?
— Приянка Алахія

1
@MatPeg Що робити у випадку, якщо я хочу мати один PrimaryKey, який створюється самостійно, а той, який надходить з REST @Entity( primaryKeys = arrayOf(COLUMN_ID_LOCAL,COLUMN_ID_REMOTE))?
— мурти

@murt Вам потрібен складений первинний ключ, але ви не можете робити того, чого хочете досягти. Читайте тут
— MatPag

Важлива частина пов’язаної документації:Insert methods treat 0 as not-set while inserting the item.
— Міха

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і автогенератор працював би належним чином.
— Міхал Баран

8
@ MichałBaran, від java doc, коли тип є примітивним java intабо long0 вважається нульовим, коли тип Integer або Long, null є нульовим. Оскільки Kotlin Int, коли нерегульований працює в JVM як примітивний int, то ви маєте рацію і var foodId: Int = 0будете працювати, але var foodId: Int? = 0не працюватимете з Int? перетворюється в JVM як цілий. @JMK, якщо ви робите 0, ви повинні зробити нерегульовані intз причини, згаданої вище.
— Allan Veloso

3
Ви можете писати без іншого способу: val jack = User(name = "Jack", phone= 1)у цьому випадку ви можете видалити 0 з конструктора
— user7856586

2
@AllanVeloso Чи можете ви пояснити, чому foodIdбуло поставлено в тіло, а не в конструктор?
— Neeraj Sewani

2
@ neer17, оскільки foodId буде автоматично генерований Room при вставці, швидше за все, не буде користі, щоб він був у конструкторі.
— Allan 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 або недійсне.

тип-2

Поставте null або zero для ідентифікатора під час створення об’єкта (мій об'єкт user user)

Якщо тип поля довгий або int (або його TypeConverter перетворює його в довгий або int), Insert методи вважають 0 не встановленим під час вставки елемента.

Якщо тип поля "Цілий" або "довгий" (об'єкт) (або його TypeConverter перетворює його в цілий чи довгий), при вставці елемента методами "Вставлення" трактуються як "не встановлені".


1
Чи можемо ми передати спеціальний ідентифікатор Entity, навіть якщо він встановлений для autoGenerate?
— ІгорГанапольський

2
@Igor Ganapolsky Так, але запис буде генеровано за допомогою цього спеціального ідентифікатора [автоматичне збільшення не буде працювати] І якщо ви повторно передасте той самий ідентифікатор, він викине виняток "UNIQUE обмеження не вдалося", тому вам потрібно завжди передавати новий ідентифікатор або вносити його [0 або null] і дозвольте автоматичному збільшенню зробити це за вас.
— кунальний хедкар

3
Чому ви навіть дозволяєте користувачеві вводити ідентифікатор у конструктор, якщо ви хочете автогенерувати?
— пекло

У Котліні ви можете використовувати клас даних та писати: val jack = User(name = "Jack", phone= 1)У цьому випадку ви можете видалити 0 з конструктора
— user7856586

@hellcast Якщо ви не включите ідентифікатор в конструктор (як я щойно навчився важкому шляху), коли ви запитуєте БД, він не призначить поле ідентифікатора (це буде просто все, що ви ініціалізуєте в конструкторі), оскільки Я припускаю, що він викликає той самий конструктор при заселенні полів об’єкта.
— Алі Хірані

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
Хоча цей фрагмент коду може бути вирішенням, включаючи пояснення, справді допомагає покращити якість вашої публікації. Пам'ятайте, що ви відповідаєте на запитання читачів у майбутньому, і ці люди можуть не знати причини вашої пропозиції щодо коду.
— Йоган

4
Є багато відповідей на кшталт "використання @PrimaryKey(autoGenerate = true)" - чи додає ваша відповідь щось нове в цю нитку?
— барбсан

так, це додає - в ньому представлено, як нуль покриває автогенеровані поля
— Маріан Падьоч

5

Наприклад, якщо у вас є usersсутність, яку ви хочете зберегти, з полями (firstname, lastname , email)і ви хочете автогенерований ідентифікатор, ви це зробите.

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

Кімната потім автоматично генерує та автоматично збільшує idполе.


22
Кожного разу, коли ми створюємо новий об’єкт Користувачі, нам потрібно буде пройти поле ідентифікатора. Чи можна цього уникнути?
— Aditya Ladwa

11
Так, поставлений @PrimaryKey(autoGenerated = true) val id: Long? = nullпоза конструктором, на корпусі класу
— Аллан Велосо

1
@Magritte Care розробити більше PLS?
— Іспам

2
@Ispam У своїй відповіді вище я розмістив, як повинен виглядати повний клас.
— Аллан Велосо

3
Насправді ви можете просто поставити 0 як ідентифікатор. Кімната автоматично генерує ідентифікатор, якщо ви встановили параметр @PrimaryKey.
— romaneso

1

Повідомте свій клас Entity за допомогою наведеного вище коду.

На Java

@PrimaryKey(autoGenerate = true)
private int id;

У Котліні

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

Потім номер автоматично автогенерується та автоматично збільшується поле id.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.