【问题标题】:How to ignore some columns during inserting date如何在插入日期期间忽略某些列
【发布时间】:2021-06-08 07:39:22
【问题描述】:

当您使用 Android Room 自动生成的插入方法时,它会将所有值传递给所有列例如,如果您有如下实体:

@Entity
public class Task {

    @PrimaryKey(autoGenerate = true)
    public long id;

    @NonNull
    @ColumnInfo(defaultValue = "Unknown Title")
    public String name;

    @NonNull
    @ColumnInfo(defaultValue = "Does not have any description!")
    public String desc;

    @ColumnInfo(defaultValue = "false")
    public boolean isDone;
}

您尝试通过以下方式插入Task 类的空实例:

taskDao.insert(new Task());

它将运行如下查询:

INSERT INTO Task (id, name, desc, isDone) values (null, null, null, 0);

这违反了我们的表结构规则,所以我们得到错误:

Caused by: android.database.sqlite.SQLiteConstraintException: NOT NULL constraint failed: task.name (code 1299 SQLITE_CONSTRAINT_NOTNULL)

如果它使用这个查询:

INSERT INTO Task DEFAULT VALUES;

INSERT INTO Task (id) VALUES (null);

SQLite 使用所有默认值创建一行,没有任何错误。

但是要忽略插入查询中的空变量以使用默认值?

【问题讨论】:

  • 你为什么不这样做:mName="Unknown title"
  • 我将使用默认值,但有空间它会将 null 传递给数据库,而不是忽略它
  • 我不明白你的意思,但如果你从 ColoumnInfo 中删除默认值并将默认值作为属性值传递,那么房间将设置此默认值如果用户错过了任何你想要的价值。
  • 你说得对,但是你所说的设置了一个将传递给数据库的值,但是 ColumnInfo 中的默认列的值将在 where 不是像这个查询 INSERT INTO TABLE task (name) values ("my task"); 这样忽略 id、描述的传递值时使用和 is_done 列
  • 我完全更新了我的问题

标签: android-room


【解决方案1】:

试试这个:

@Entity
public class Task {
    public String mName = "Unknown Title";
    public String mDescription = "Does not have any description!";
    public boolean mIsDone  = "false";

    @PrimaryKey(autoGenerate = true)    //must be placed at the end!!
    public long id = 0;
}

然后像这样创建对象:

Task task = new Task()    //all use default values

Task task = new Task(name)    //use default values for other fileds

Task task = new Task(name, description)    //the order matters, otherwise you need to explicitlty specify the filed, like following

Task task = new Task(mIsDone = true, mName = "Sam")

【讨论】:

  • 为什么id一定要放在最后??
  • @Mohammad7G 有帮助吗?
  • 关于你答案的第一部分,注意我的问题,我解释说它通过了 null。在第 2 部分中,Room 似乎没有直接处理我的问题
  • @Mohammad7G 你得到 null 是因为你没有给那个字段提供默认值 man,columnInfo(defaultValue) 不能按你期望的方式工作,它是用于迁移的:developer.android.com/training/data-storage/room/…。试试看吧。
【解决方案2】:

基于Android documentation中所写的内容:

如果您只是将Entity@Insert 一起插入,则不会使用您在此处指定的默认值。

这意味着没有简单的方法,但您可以通过某些方式做到:

  1. 分配变量值

为这些变量值分配您在@ColumnInfo 中定义为默认值的值,因为如果您不更新这些值,将使用默认分配,正如Documentation 所说:

如果您只是插入 Entity@Insert ... 将使用在 Java/Kotlin 中分配的任何值。

@Entity
public class Task {

    @PrimaryKey(autoGenerate = true)
    public long id;

    @NonNull
    @ColumnInfo(defaultValue = "Unknown Title")
    public String name = "Unknown Title";

    @NonNull
    @ColumnInfo(defaultValue = "Does not have any description!")
    public String description = "Does not have any description!";

    @ColumnInfo(defaultValue = "false")
    public boolean isDone; // it doesn't need assignment
                           // boolean values are false as default
}
  1. 特殊查询

作为Documentation推荐:

@QueryINSERT 语句一起使用并在此处跳过此列以使用此默认值。

@Query("INSERT INTO task DEFAULT VALUES")
long insert();

@Query("INSERT INTO task (id) VALUES (null)")
long insert();

正如你在问题中所说的那样。

  1. 简化类 (ref)
@Insert(entity = Task.class)
long insert(NewTask task);

@Entity
class NewTask {
    int id = 0;
}

它运行

INSERT INTO task (id) VALUES (null);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-07-06
    • 1970-01-01
    • 2019-10-19
    • 2021-03-10
    • 1970-01-01
    • 1970-01-01
    • 2017-12-07
    • 1970-01-01
    相关资源
    最近更新 更多