android – 有没有办法让Room生成一个没有AUTOINCREMENT的自动生成主键?

我的房间数据库具有以下实体:

@Entity
public class SmsMessage {
    @PrimaryKey
    public long id;

    public boolean incoming;
    public String sender;
    public String receiver;
    public String body;
    public long timestamp;
}

尝试将多个项插入数据库时​​,此操作失败并出现以下RuntimeException:

sqliteConstraintException: PRIMARY KEY must be unique (code 19)

生成sql CREATE TABLE语句如下所示:

CREATE TABLE `SmsMessage` (
    `id`    INTEGER NOT NULL,
    `incoming`  INTEGER NOT NULL,
    `sender`    TEXT,
    `receiver`  TEXT,
    `body`  TEXT,
    `timestamp` INTEGER NOT NULL,
    PRIMARY KEY(`id`)
);

这似乎与INTEGER NOT NULL PRIMARY KEY不同,即使我在the SQLite documentation中找不到此行为的任何文档.

似乎我必须使用@PrimaryKey(autogenerate = true)才能使Room自动生成主键值.使用autogenerate = true查看生成数据库时,会生成以下sql

CREATE TABLE `SmsMessage` (
    `id`    INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
    `incoming`  INTEGER NOT NULL,
    `sender`    TEXT,
    `receiver`  TEXT,
    `body`  TEXT,
    `timestamp` INTEGER NOT NULL
);

似乎autogenerate = true对应于sqlite AUTOINCREMENT.但是,the SQLite documentation非常清楚,不需要AUTOINCREMENT(在大多数情况下不推荐),以便自动生成唯一的主键. AUTOINCREMENT的目的基本上是为了防止重复使用已删除但已删除的主键.

The AUTOINCREMENT keyword imposes extra cpu, memory, disk space, and disk I/O overhead and should be avoided if not strictly needed. It is usually not needed.

In sqlite, a column with type INTEGER PRIMARY KEY is an alias for the ROWID (except in WITHOUT ROWID tables) which is always a 64-bit signed integer.

On an INSERT, if the ROWID or INTEGER PRIMARY KEY column is not explicitly given a value, then it will be filled automatically with an unused integer, usually one more than the largest ROWID currently in use. This is true regardless of whether or not the AUTOINCREMENT keyword is used.

If the AUTOINCREMENT keyword appears after INTEGER PRIMARY KEY, that changes the automatic ROWID assignment algorithm to prevent the reuse of ROWIDs over the lifetime of the database. In other words, the purpose of AUTOINCREMENT is to prevent the reuse of ROWIDs from prevIoUsly deleted rows.

因此,似乎通常不需要也不建议使用@PrimaryKey(autogenerate = true).但仅仅使用@PrimaryKey根本不会自动生成值.

我怎么告诉Room我想要的是’id’INTEGER NOT NULL PRIMARY KEY?

解决方法:

目前这是不可能的 – 唯一的选择是AUTOINCREMENT.您可以为existing feature request提供支持此用例的进度更新.

相关文章

SQLite架构简单,又有Json计算能力,有时会承担Json文件/RES...
使用Python操作内置数据库SQLite以及MySQL数据库。
破解微信数据库密码,用python导出微信聊天记录
(Unity)SQLite 是一个软件库,实现了自给自足的、无服务器...
安卓开发,利用SQLite实现登陆注册功能