Android Sqlite INSERT OR REPLCACE 主键非 _id
前题: 今天遇到一个问题,我们本地存了多条评论来自不同的表。
原本的设计是拿服务器上的id直接当成本地的 _id 字段,但是一样是来自不同的表,这样就会出现id有可能重复的问题,所以当我想本地和服务器同步数据时 使用 INSERT OR UPDATE 就会出现问题。
因为出现了上述问题,所以我就开始想之前的在的数据是怎么实现的。 于是 查看之前的代码。
"insert or replace into "
+ TABLE_NAME_CATEGORY_ARTICLES + "("
+ FIELDS_CATEGORY_ARTICLES + ") values ”
+ "(?, ?, ?, ?, ?, ?, ?, ?)";
从这段代码里没有发现任何用于判断是决定更新还是新建,所以再向前……
"CREATE TABLE IF NOT EXISTS "
+ TABLE_NAME_CATEGORY_ARTICLES
+ "(_id INTEGER PRIMARY KEY,"
+ "category TEXT, " + "title TEXT, "
+ "summary TEXT, " + "content TEXT, "
+ "created_at TIMESTAMP, "
+ "readFlg BOOLEAN, " + "thumbnail TEXT)";
我们找到了建表语句,在这里只发现了,primary key, 再没有其它的东西了,所以我推测它应该是通过 _id 这个primary key来确定是否存在这条记录来决定 是更新还是新建。 这了确定我的推测是正确的,我google了一下,果然……
回到我之前的问题,我们现在不能使用 _id 这个主键来确定是更新还是插入了。于是我就查一下文档,发现 sqlite 可以有另一种方式来约束这样的功能, 那就是
索引
于是又回到我们的建表语句中:
"CREATE TABLE IF NOT EXISTS "
+ TABLE_NAME_COMMENT_AT_ME
+ "( _id INTEGER PRIMARY KEY AUTOINCREMENT, id LONG, quote text, uid LONG, display_name text, avatar_url text, content text, type text, original_id LONG, create_at DATE, login text)";
根据我的要求可以确定一条是 id 有可能重复,并且 original_id也有可能重复 所以我打算使用
联合索引
那么就需要确定使用哪两个字段。
这里我考虑了一下,对应服务器上表,每一个
type
一个表,所以我想使用 type
和 id
联合做为索引来确定一条数据的唯一性。这样我就可以使用 INSERT OR REPLACE
来确定一条记录是更新还是新建了。
所以,问题到这里我们基本确定方案。 所以查一下文档,在sqlite下面如何建索引,这个不难。
"CREATE UNIQUE INDEX IF NOT EXISTS "
+ INDEX_NAME_COMMENT_AT_ME
+ " ON " + TABLE_NAME_COMMENT_AT_ME + " (id, type)";
但是在Android中不是只有建一个事情,对应升级时的删除事件也应该有,所以我们就先预备一下吧:
"DROP INDEX IF EXISTS " + INDEX_NAME_COMMENT_AT_ME;
到这里你可能会想,应该打完收工了吧。
错了做为程序员,我们应该严谨一点(因为我经常不够严谨,
错了做为程序员,我们应该严谨一点(因为我经常不够严谨,
石爷
常教育我,所以久而久之也形成了习惯了) 我们还需要进行确定,确保我们的工作是正确并且有效的。于是我拿了一条数据手工来操作一下。
最终得到一条结论: > 在Sqlite 里使用 INSERT OR REPLACE 如果记录不存在插入成功。 > 如果记录已经存在,会删除之前的记录,重新插入一条新的记录 > 如果 _id 是自增长字段你就可以看出它是这样做的
好了,这下我们可以打完收工了,最后我想说一句:
大哥,我写了这么长,给个评论吧!
评论
发表评论