Добавить уникальное ограничение в базе данных комнаты в несколько столбцов
У меня есть одна сущность в комнате
@Entity(foreignKeys ={
@ForeignKey(entity = Label.class, parentColumns = "_id", childColumns = "labelId", onDelete = CASCADE),
@ForeignKey(entity = Task.class, parentColumns = "_id", childColumns = "taskId", onDelete = CASCADE)
})
public class LabelOfTask extends Data{
@ColumnInfo(name = "labelId")
private Integer labelId;
@ColumnInfo(name = "taskId")
private Integer taskId;
}
Синтаксис SQL этого объекта, как показано ниже
CREATE TABLE `LabelOfTask` (
`_id` INTEGER PRIMARY KEY AUTOINCREMENT,
`labelId` INTEGER,
`taskId` INTEGER,
FOREIGN KEY(`labelId`) REFERENCES `Label`(`_id`) ON UPDATE NO ACTION ON DELETE CASCADE ,
FOREIGN KEY(`taskId`) REFERENCES `Task`(`_id`) ON UPDATE NO ACTION ON DELETE CASCADE
);
но какое изменение или аннотацию мне нужно добавить в класс сущности, если я хочу добавить ограничение ниже к автоматически сгенерированной схеме sql таблицы
unique (labelId, taskId)
В конечном счете, я хочу сделать комбинацию labelId и taskId уникальной в таблице (или объекте комнаты), используя библиотеку комнаты.
5 ответов
Простое УНИКАЛЬНОЕ ограничение для столбца, кроме как через индекс, не поддерживается.
Вы можете применить это свойство уникальности, установив для уникального свойства аннотации @Index значение true. Следующий пример кода не позволяет таблице иметь две строки, содержащие одинаковый набор значений для столбцов firstName и lastName:
@Entity(indices = {@Index(value = {"first_name", "last_name"},
unique = true)})
class User {
@PrimaryKey
public int id;
@ColumnInfo(name = "first_name")
public String firstName;
@ColumnInfo(name = "last_name")
public String lastName;
@Ignore
Bitmap picture;
}
В вашем коде вы можете сделать следующие изменения, чтобы иметь уникальные ограничения
@Entity(foreignKeys ={
@ForeignKey(entity = Label.class, parentColumns = "_id", childColumns = "labelId", onDelete = CASCADE),
@ForeignKey(entity = Task.class, parentColumns = "_id", childColumns = "taskId", onDelete = CASCADE)},
indices = {@Index(value = {"labelId", "taskId"},
unique = true)}
)
public class LabelOfTask extends Data{
@ColumnInfo(name = "labelId")
private Integer labelId;
@ColumnInfo(name = "taskId")
private Integer taskId;
}
Если вам интересно сделать один столбец уникальным, нужно всего лишь написать
@Entity(indices = {@Index(value = "name", unique = true)})
Для одного столбца Уникальность
@Entity(indices = {@Index(value = {"first_name"},unique = true)})
Для уникальности нескольких столбцов
@Entity(indices = {@Index(value = {"first_name", "last_name"},unique = true)})
Не могу комментировать, поэтому просто добавлю сюда. При ручной миграции вашей базы данных Room DB для добавления индекса с помощью операторов SQL ваше имя индекса, чтобы оно могло соответствовать аннотации в таблице, должно иметь формат:
...
database.execSQL("CREATE UNIQUE INDEX index_tableName_columnName ON tableName (columnName)")
...
Не уверен, насколько длинными могут быть имена индексов, поэтому не уверен, как это выглядит с индексами с несколькими столбцами.
Вы также можете добиться уникальности нескольких столбцов с помощью составного первичного ключа (объект уникально идентифицируется комбинацией нескольких столбцов).
@Entity(primaryKeys = ["firstName", "lastName"])
data class User(
val firstName: String?,
val lastName: String?
)
Обратите внимание, что в этом случае вы не можете использовать автоматически созданное приращение идентификатора, SQLite это не поддерживает .