为在 Sqlite 中具有 LONG 数据类型的字段的表创建房间实体

Posted

技术标签:

【中文标题】为在 Sqlite 中具有 LONG 数据类型的字段的表创建房间实体【英文标题】:Create Room Entity for a Table which has a field with LONG datatype in Sqlite 【发布时间】:2019-05-30 19:13:32 【问题描述】:

App Database 有 Items 表,其中有一列 Price,数据类型为 Long。 数据库版本 = 1

CREATE TABLE items (_id INTEGER PRIMARY KEY AUTOINCREMENT,item_id 
INTEGER,title TEXT,price LONG, UNIQUE (item_id) ON CONFLICT IGNORE)

在尝试迁移到 Room 时,我遇到了以下问题

java.lang.IllegalStateException: Migration didn't properly handle items(moka.pos.test.data.entity.Item).

Expected : price=Columnname='price', type='INTEGER', affinity='3', notNull=false, primaryKeyPosition=0
Found : price=Columnname='price', type='LONG', affinity='1', notNull=false, primaryKeyPosition=0

这是我的 Item 实体类

@Entity(tableName = "items")
public class Item 

@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = "_id")
private Integer _ID;

@ColumnInfo(name = "item_id")
private Integer id;

@ColumnInfo(name = "title")
private String title;

@ColumnInfo(name = "price")
private Long price;

public Integer get_ID() 
    return _ID;


public void set_ID(Integer _ID) 
    this._ID = _ID;


public Integer getId() 
    return id;


public void setId(Integer id) 
    this.id = id;


public String getTitle() 
    return title;


public void setTitle(String title) 
    this.title = title;


public Long getPrice() 
    return price;


public void setPrice(Long price) 
    this.price = (long) (getId() * AppUtil.getRandomNumber(10, 99));


从 SQLiteOpenHelper 迁移到 Room 时,如何使 Room 实体字段支持 Long 数据类型。

【问题讨论】:

【参考方案1】:

如果有人仍在为此苦苦挣扎,就像我做了几个小时一样,并且不理解上述解决方案......只需在 SQLite 中创建一个新的数据库文件,复制用于创建表的 SQL 语句,但将每个数据类型更改为 TEXT , INTEGER, BLOB, REAL 和 UNDEFINED,。然后使用从旧数据库复制的 SQL 语句填充表。修复了在 SQLite 中简单地更改数据类型没有的问题。

【讨论】:

【参考方案2】:

由于文档 SQLITE 不支持 Long,请在此处查看 docs。

整数。该值是一个有符号整数,存储在 1、2、3、4、6 或 8 中 字节数取决于值的大小。

但是LONG是8个字节,INTEGER也可以保存8个字节的值,你可以使用INTEGER

【讨论】:

感谢您的建议 我在这里有点困惑。您的意思是 sql 中的“lNTEGER”类型的大小为 8 个字节,与 java 的“long”数据类型(8 个字节)的大小范围相同?因为int的数据类型是4字节大小。 你好@anshsachdeva,我相信上面的答案 karan 谈到了 SQL Lite 中的 INTEGER 属性类型及其在 SQLite 中的大小。如果我错了,请纠正我。 @anshsachdeva 如答案中所引用,SQLite 中的 INTEGER 可能有 1、2、3、4、6 或 8 个字节,因此您可以将 java 的 8 字节长 Long 放入 SQLite 的 INTEGER 中跨度> 【参考方案3】:

简单的答案是你不能

房间只支持TEXTINTEGERBLOBREALUNDEFINED这5种数据类型。

所以,BooleanIntegerLong 的 java 数据类型将在 SQL 中全部转换为 INTEGER

您可以做的是在SQL 中将LONG 数据类型转换为INTEGER,而不是在Room 中将INTEGER 数据类型转换为LONG为了让 Room 支持 LONG,Room 不支持。

【讨论】:

感谢您的建议

以上是关于为在 Sqlite 中具有 LONG 数据类型的字段的表创建房间实体的主要内容,如果未能解决你的问题,请参考以下文章

SQLite 中是不是有 Long 类型?

字长和数据类型

字长和数据类型

SQLite - 将 MySQL 触发器转换为在 SQLite 上工作

请问Sqlite 中 string和text 两种数据类型有啥区别

Android中SQLite的Cursor如何取得boolean型数据