【发布时间】:2013-06-06 22:07:01
【问题描述】:
我正在使用 ORMlite,我想知道是否可以在一个表中包含多个标识列。
我有一个表,其中包含两个特定列:ID 和 Number。如果 ID 和 Number 相同,我希望 ORMlite 只更新该行,否则它应该创建一个新行。我正在使用方法createOrUpdate。
谢谢。
【问题讨论】:
我正在使用 ORMlite,我想知道是否可以在一个表中包含多个标识列。
我有一个表,其中包含两个特定列:ID 和 Number。如果 ID 和 Number 相同,我希望 ORMlite 只更新该行,否则它应该创建一个新行。我正在使用方法createOrUpdate。
谢谢。
【问题讨论】:
如果 ID 和 Number 相同,我希望 ORMlite 只更新该行,否则它应该创建一个新行(我正在使用方法 createOrUpdate)。
是的,您将无法使用createOrUpdate(...),但是您应该能够添加自己的 DAO 方法来很好地模拟它。如果 ID 不是唯一的,那么您需要创建另一个 ID 字段作为身份,并使用您的 ID 作为另一个字段,可能带有 uniqueCombo 限制。
@DatabaseField(generatedId = true)
private int uniqueId;
// not the id field because it is not unique
@DatabaseField
private int id;
@DatabaseField
private int number;
在您的 DAO 类中,覆盖 BaseDaoImpl 类并覆盖 createOrUpdate(...) 方法。它应该执行以下操作:
public CreateOrUpdateStatus createOrUpdate(Foo data) throws SQLException {
QueryBuilder<Foo, Integer> qb = queryBuilder();
// NOTE: id here is not the identity field
qb.where().eq("id", data.id).and().eq("number", data.number);
Foo existing = qb.queryForFirst();
if (existing == null) {
int numRows = create(data);
return new CreateOrUpdateStatus(true, false, numRows);
} else {
int numRows = update(data);
return new CreateOrUpdateStatus(false, true, numRows);
}
}
作为一种优化,您可以使用 ThreadLocalSelectArg 参数为 id 和 number 参数预先创建该查询,然后只需设置参数并在 createOrUpdate(...) 方法中运行查询。
【讨论】:
else 的情况下,在调用update(data) 之前是否必须将现有Foo 条目的uniqueId 字段分配给data 对象?因为否则,Dao 将不知道要更新哪一行。此外,在调用create(data) 之前,您必须确保data 项的uniqueId 字段不存在于数据库表中。
existing 与 data 具有相同的 id 和 number 因为查询。这应该意味着uniqueId是一样的。如果不是,则发生了一些数据不一致。
else{...} 的情况下,它仍然可能意味着data 的uniqueId 字段没有设置:想想你的情况从 API 获取 data 项目(仅返回 id 和 number 字段,而不是该项目的本地 uniqueId)并且您希望使用 createOrUpdate() 将其保存在数据库中。我想说,当您使用 ORMlite 同步远程和本地数据时,这种情况很常见。
通读这篇文章和 ORMLite 文档; Multiple primary keys - ORMlite
我不能 100% 确定这个答案。 uniqueCombo = true 似乎是一个不错的猜测,但我不确定诸如更新和删除之类的东西是否仍然有效。你必须自己测试它。
【讨论】: