简体   繁体   English

如果我们有更多列,如何在房间数据库表中只插入 3 列数据?

[英]How to insert only 3 columns data in room database table if we have more columns?

I have a project that I wrote in kotlin.我有一个在 kotlin 中编写的项目。 I want to insert data in different columns of the same table on different pages.我想在不同页面上的同一个表的不同列中插入数据。 I have specified these columns in the dataclass, but it gives a null data error.我已经在数据类中指定了这些列,但它给出了 null 数据错误。

In order to make this insert process more healthy, should I divide the table into two separate tables or send static 'null' data and update these fields?为了让这个插入过程更健康,我应该把表分成两个单独的表还是发送 static 'null' 数据并更新这些字段?

In a database, such as SQLite (which Room is a wrapper around), the unit of insertion is a row.在数据库中,例如 SQLite(Room 是一个包装器),插入单位是一行。

A row will consist of the same number of columns.一行将由相同数量的列组成。 You cannot insert a column on it's own, other than if you ALTER the table to add or remove a column, when the change is reflected throughout the entire table.当更改反映在整个表中时,您不能单独插入列,除非您更改表以添加或删除列。

  • if adding a column then a DEFAULT VALUE must be provided, this could be the default/implicit value of null or another specific value.如果添加列,则必须提供默认值,这可以是 null 的默认/隐式值或其他特定值。
  • Room with Kotlin will apply a constraint (rule) of NOT NULL unless nulls are specifically allowed using for example ?带有 Kotlin 的房间将应用 NOT NULL 的约束(规则),除非特别允许使用例如?
    • var theColumn: Int has the implicit NOT NULL var theColumn: Int具有隐式 NOT NULL
    • var theColumn: Int? does not have the implicit NOT NULL and nulls can be stored没有隐式 NOT NULL 并且可以存储空值
    • var theColumn: Int=-1 will apply a default value of -1 in the absence of the field not being supplied a value when instantiating the object. var theColumn: Int=-1将在实例化 object 时在没有提供值的字段的情况下应用默认值 -1。
    • var theColumn: Int?=null will apply null in the absence of the field not being supplied a value when instantiating the object. var theColumn: Int?=null将应用 null 在实例化 object 时没有提供值的字段。
      • obviously fields may be altered before inserting the object, if var rather than val is used.显然,如果使用 var 而不是 val,则在插入 object 之前可能会更改字段。

The data stored in the column can be interpreted to represent whatever you wish, often NULL will be used to represent a special situation such as no value.存储在列中的数据可以解释为代表任何你想要的,通常 NULL 会用于表示没有值等特殊情况。

If using an @Insert annotated function, then ALL columns are applied the values as obtained from the object or objects passed to the function.如果使用带有@Insert注释的 function,则所有列都将应用从 object 或传递给 function 的对象中获得的值。 In Kotlin whether or not NULLs can be used is dependent upon the field definition or in some cases the @NonNull annotation.在 Kotlin 中是否可以使用 NULL 取决于字段定义或在某些情况下 @NonNull 注释。

@Insert indicates what is termed as a convenience method, it actually builds the underlying SQL along with binding the values using the SQLite API. @Insert表示所谓的便捷方法,它实际上构建底层 SQL 并使用 SQLite API 绑定值。

However, if you want flexibility, then an @Query annotation with suitable INSERT SQL statement can be used.但是,如果您想要灵活性,则可以使用带有合适 INSERT SQL 语句的@Query注释。

eg you could perhaps have a table that has 4 columns COL1, COL2, COL3 and COL4 and only apply some of the columns (the DEFAULT VALUE will be applied to the other column if specified, if not the NULL but if there is a NOT NULL constraint then a conflict would be raised).例如,您可能有一个包含 4 列 COL1、COL2、COL3 和 COL4 的表,并且只应用一些列(如果指定,默认值将应用于另一列,如果不是 NULL 但如果存在 NOT NULL约束,则将引发冲突)。

So to insert when only two of the columns (COL2 and COL4) then you could use:-因此,当只有两列(COL2 和 COL4)时插入,您可以使用:-

@Query("INSERT INTO theTable (COL2,COL4) VALUES(:valueForCol2,:valueForCol4)")
fun insertCol2AndCol4Only(valueForCol2: Int, valueForCol4: Int?)

Note that valueForCol4 could be NULL.请注意, valueForCol4可能是 NULL。 However, whether or not a NULL will result in a conflict depends upon how the field is defined in the @Entity annotated class.但是,NULL 是否会导致冲突取决于在 @Entity 注释的 class 中如何定义该字段。

Conflicts (breaking a rule) can be handled by SQLite, depending upon the type of the conflict. SQLite 可以处理冲突(违反规则),具体取决于冲突的类型。 UNIQUE, PRIMARY KEY (which is really a UNIQUE conflict), CHECK (Room doesn't cater for CHECK constraints) and NOT NULL constraints can be handled in various ways at the SQLite level.可以在 SQLite 级别以各种方式处理 UNIQUE、PRIMARY KEY(实际上是 UNIQUE 冲突)、CHECK(房间不满足 CHECK 约束)和 NOT NULL 约束。

A common use of conflict handling is to IGNORE the conflict, in which case the action (INSERT or UPDATE) is ignored.冲突处理的一个常见用途是忽略冲突,在这种情况下,操作(INSERT 或 UPDATE)被忽略。 In the case of INSERT the row is not inserted but SQLite ignores the conflict and doesn't issue an error.在 INSERT 的情况下,未插入行,但 SQLite 忽略冲突并且不发出错误。

So if for example COL4's field was var COL4: Int and not var COL4: Int?因此,如果例如 COL4 的字段是var COL4: Int而不是var COL4: Int? then the insert would fail and an SQlite Exception would occurr.那么插入会失败,并且会发生 SQlite 异常。

However if instead但是,如果相反

@Query("INSERT OR IGNORE INTO theTable (COL2,COL4) VALUES(:valueForCol2,:valueForCol4)")

were used and the COL4 field were defined as var COL4: Int (implied NOT NULL constraint) then the conflict if NULL was passed as valueForCol4 then the row would not be inserted but no failure would occur as the NOT NULL conflict would be ignored. were used and the COL4 field were defined as var COL4: Int (implied NOT NULL constraint) then the conflict if NULL was passed as valueForCol4 then the row would not be inserted but no failure would occur as the NOT NULL conflict would be ignored.

With the @Insert annotation you can defined this conflict handling via the onConflictStrategy parameter eg @Insert(onConflictStrategy=OnConflict.IGNORE)使用@Insert注释,您可以通过 onConflictStrategy 参数定义此冲突处理,例如@Insert(onConflictStrategy=OnConflict.IGNORE)

You may wish to consider reading the following:-您不妨考虑阅读以下内容:-

In order to make this insert process more healthy, should I divide the table into two separate tables or send static 'null' data and update these fields?为了让这个插入过程更健康,我应该把表分成两个单独的表还是发送 static 'null' 数据并更新这些字段?

Note the above is only a summary, INTEGER PRIMARY KEY aka @PrimaryKey var id: Long?=null or variations such as @PrimaryKey(autoGenerate=true) etc has specifically not been discussed.注意以上只是一个总结,INTEGER PRIMARY KEY aka @PrimaryKey var id: Long?=null或诸如@PrimaryKey(autoGenerate=true)等的变化没有具体讨论。

The design of the database could be handled either way, from the very limited description of the scenario, a most likely suitable scenario cannot really be advised, although either could probably be an approach.数据库的设计可以通过任何一种方式处理,从对场景的非常有限的描述来看,不能真正建议最可能合适的场景,尽管任何一种都可能是一种方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM