跳至主要内容

Android Sqlite INSERT OR REPLCACE index


Android Sqlite INSERT OR REPLCACE 主键非 _id

Sqlite database
前题: 今天遇到一个问题,我们本地存了多条评论来自不同的表。
原本的设计是拿服务器上的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)";
create index of sqlite
但是在Android中不是只有建一个事情,对应升级时的删除事件也应该有,所以我们就先预备一下吧:
"DROP INDEX IF EXISTS " + INDEX_NAME_COMMENT_AT_ME;
drop index of sqlite
到这里你可能会想,应该打完收工了吧。
错了做为程序员,我们应该严谨一点(因为我经常不够严谨,石爷 常教育我,所以久而久之也形成了习惯了) 我们还需要进行确定,确保我们的工作是正确并且有效的。于是我拿了一条数据手工来操作一下。
最终得到一条结论: > 在Sqlite 里使用 INSERT OR REPLACE 如果记录不存在插入成功。 > 如果记录已经存在,会删除之前的记录,重新插入一条新的记录 > 如果 _id 是自增长字段你就可以看出它是这样做的
insert or replace result
好了,这下我们可以打完收工了,最后我想说一句:大哥,我写了这么长,给个评论吧!

评论

此博客中的热门博文

How to change ViewPager scroll animation duration and velocity

When you call change current selected view pager position you may call like this. // change current position default is viewPager.setCurrentItem(position, true); viewPager . setCurrentItem ( position ); There will show transaction animation for change position , but this animation is too fast. So I want change this animation. When I see source code I find this, like flow. where is the scroll animation and speed.     int duration = 0 ;     velocity = Math . abs ( velocity );     if ( velocity > 0 ) {         duration = 4 * Math . round ( 1000 * Math . abs ( distance / velocity ));     } else {         final float pageWidth = width * mAdapter . getPageWidth ( mCurItem );         final float pageDelta = ( float ) Math . abs ( dx ) / ( pageWidth + mPageMargin );         duration = ( int ) (( pageDelta + 1 ) * 100 );     }     duration = Math . min ( duration , MAX_SETTLE_DURATION );     mScroller . startScroll ( sx , sy , dx , d

how to open context menu for android listview item button

Like title, here is this problem in my activity like this: An more button in every row of listview item . When I click this more button then show activity context menu. So I try to click button, but open context menu is the Adaper's context menu. My  Adapter  is extends from BaseAdapter ,  BaseAdapter  has not context menu. My solution like example : <ImageButton android:id="@+id/more" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_centerVertical="true" android:layout_marginRight="15dp" android:background="#00000000" android:src="@drawable/btn_addressbook_more" android:onClick="onMoreClick"/> Add an event named  onMoreClick , when user click this button will do  onClick  event in  activity . // maybe you can registe

How to use Realm database in Kotlin

Hot to use Realm in android project. Befor you use realm we should be read documentation https://realm.io/docs/java/latest#getting-started Then we got the way how to install. Install Realm as a Gradle plugin. Setp 1:   change build.gradle in project level buildscript { repositories { jcenter() } dependencies { classpath "io.realm:realm-gradle-plugin:5.14.0" } } Step 2:   Apply the realm-android plugin to the top of the application level build.gradle file. Create reaml map Object There has two way for mapping Object Make   Object   extends   ReamlObject Or make   Object   implement   ReamlModel Declear reaml mapping objects Realm not support   data class   yet. So we can't use it now. And object will make it open, because Realm object will generate subclass after   aapt   or   kapt . // 1. open class User : RealmObject() { var id: String = UUID . random UUID() . to String() var name: String = "