web-dev-qa-db-fra.com

Aucune contrainte "NOT NULL" et "UNIQUE" sur la bibliothèque de persistance de la pièce

En jouant avec Room Persistence Library , je me suis rendu compte qu’il n’existait pas de méthodologie pour définir un champ de classe de données avec des contraintes NOT NULL et UNIQUE. si SQLite supporte ces contraintes. N’est-ce pas un problème de migrer l’ancienne base de données où ces contraintes sont utilisées? Quelqu'un peut-il faire une suggestion pour ce problème?

8

J'ai appris qu'il n'y avait pas de méthodologie pour définir un champ de classe de données avec des contraintes NOT NULL et UNIQUE

Une annotation @NonNull sur un champ @Entity entraîne l'application de NOT NULL à la colonne de ce champ.

unique=true sur un @Index appliquera une contrainte d'unicité (par exemple, @Entity(indices={@Index(value="something", unique=true)}). Cependant, vous avez raison de dire qu'une contrainte UNIQUE sur une colonne, autre que via un index, n'est pas prise en charge.

N’est-ce pas un problème de migrer l’ancienne base de données où ces contraintes sont utilisées?

Room n'est pas conçu pour prendre en charge les structures de base de données existantes, en particulier dans l'état actuel alpha. Au fil du temps, je m'attendrais à ce que Room prenne en charge un pourcentage plus élevé de fonctionnalités SQLite, mais je serais abasourdi s'il atteignait un jour 100%.

32
CommonsWare

Réponse complémentaire à propos de NOT NULL pour ceux qui utilisent Kotlin:

notez que marquer un type comme non optionnel le rendra automatiquement non nul (et un type optionnel ne le fera pas).

Vous pouvez le vérifier dans le schéma généré par room avec @Database(exportSchema = true) sur votre base de données.

Par exemple, j'ai quelque chose comme ça:

@Entity(tableName = "messages")
data class Message (
        @PrimaryKey
        val messageId: UUID = UUID.randomUUID(),
        val date: Date = Date(),
        val receivedDate: Date? = null
)

Et dans le schéma généré, je peux lire:

"CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`messageId` TEXT NOT NULL, `date` INTEGER NOT NULL, `receivedDate` INTEGER, PRIMARY KEY(`messageId`))"

(Remarque: le type Date est ici une Int et l'UUID une chaîne due aux convertisseurs que j'utilise ailleurs)

3
Vincent Hiribarren

pour un champ valide, vous pouvez utiliser le type primitif wrapper Java. par exemple, utilisez Integer instance int dans votre Room Room. comme dans wrapper type primitif Java ceci peut être nul mais le type primitif classe cant bee nul. et dans la génération de ce code SQL pour le champ primitif qui utilise notNull = true, mais lorsque vous utilisez Integer dans le code SQL, utilisez notNull = false

1
Mahdi Azadbar

Si vous avez plusieurs éléments à marquer comme uniques et basés sur ceux que vous souhaitez insérer dans la base de données, vous pouvez utiliser une clé primaire composite.

Pour la valeur Non null, Room a fourni l'annotation "@NonNull" ajoutée au champ qui ne peut pas être null.

Dans le ci-dessous mentionné par exemple. Le numéro de rôle est unique dans chaque classe, mais 2 classes différentes peuvent avoir le même numéro de rôle. Nous pouvons donc utiliser class & rollNumber comme clé primaire composite et insérer dans la base de données de manière unique . Exemple: 

    @Entity(primaryKeys = {"rollNumber", "class"})   
    class Student {
       @NonNull
        private int rollNumber;
        private String firstName;
        private String lastName;
        private int class;
        } 
0
Ashish John