关于ContentProvider 使用replace

来源:互联网 发布:淘宝宝贝图片复制 编辑:程序博客网 时间:2024/05/17 21:56

sql语句 INSERT  OR REPLACE 作用就是插入一个对象。先去数据库对比有没有该对象。如果存在就把原来的数据替换。如果没有就进行插入操作。

这样做的好处就是不用再操作前去查询 这个对象是否存在,然后再选择是跟新这条数据或者重新插入。这样减少操作数据库一次。


contentProvider怎么定义我就不对多说了。

再我们继承自ContentProvider类的之类中覆写一个 public Uri insert(Uri uri, ContentValues values)方法去实现replace方法。

@Overridepublic Uri insert(Uri uri, ContentValues values){// TODO Auto-generated method stub// LogUnit.Log(TAG, uri+"");int typecode = uriMatcher.match(uri);//long id = db.insert("user", BaseColumns._ID, values);long id = db.insertWithOnConflict("user", BaseColumns._ID, values, SQLiteDatabase.CONFLICT_REPLACE);if (id >= 0){Uri result = ContentUris.appendId(        uri.buildUpon(), id).build();getContext().getContentResolver().notifyChange(uri, null, true);return result;}else{throw new SQLException("Fail to insert to row :" + uri);}}


我这是简单用了表名 “user”  实际上应该用typeCode去按照自己要求得到相应的表名。

db调用的

db.insertWithOnConflict("user", BaseColumns._ID, values, SQLiteDatabase.CONFLICT_REPLACE);

这个方法查看SQLiteDatabase的源码

public long insertWithOnConflict(String table, String nullColumnHack,            ContentValues initialValues, int conflictAlgorithm) {        acquireReference();        try {            StringBuilder sql = new StringBuilder();            sql.append("INSERT");//在这 sql语句中加入了 or replace的命令            sql.append(CONFLICT_VALUES[conflictAlgorithm]);            sql.append(" INTO ");            sql.append(table);            sql.append('(');            Object[] bindArgs = null;            int size = (initialValues != null && initialValues.size() > 0)                    ? initialValues.size() : 0;            if (size > 0) {                bindArgs = new Object[size];                int i = 0;                for (String colName : initialValues.keySet()) {                    sql.append((i > 0) ? "," : "");                    sql.append(colName);                    bindArgs[i++] = initialValues.get(colName);                }                sql.append(')');                sql.append(" VALUES (");                for (i = 0; i < size; i++) {                    sql.append((i > 0) ? ",?" : "?");                }            } else {                sql.append(nullColumnHack + ") VALUES (NULL");            }            sql.append(')');            SQLiteStatement statement = new SQLiteStatement(this, sql.toString(), bindArgs);            try {                return statement.executeInsert();            } finally {                statement.close();            }        } finally {            releaseReference();        }    }public long insert(String table, String nullColumnHack, ContentValues values) {        try {            return insertWithOnConflict(table, nullColumnHack, values, CONFLICT_NONE);        } catch (SQLException e) {            Log.e(TAG, "Error inserting " + values, e);            return -1;        }    }private static final String[] CONFLICT_VALUES = new String[]            {"", " OR ROLLBACK ", " OR ABORT ", " OR FAIL ", " OR IGNORE ", " OR REPLACE "};

可以看到 insert() 方法实际上还是调用insertWithOnConflict()方法,只是CONFLICT_VALUES数据中取的是第一个值。所以insert()只是插入操作,冲突没有处理。
对于冲突即数据相同的判断是依据这个表所建的索引进行区分。 


user 表有(_id,id,name,phone)4个属性。我们通过id区分。id作为判断依据。_id是自增长主键。
那么我们先要对id进行建立索引。


db.execSQL("DROP INDEX IF EXISTS "+INDEX_NAME);db.exeSQL("create unique index "+ INDEX_NAME+" on "+tableName+"(id)");

然后我们测试: 先插入一条数据。

ContentValues values = new ContentValues();values.put("id", 1);values.put("name", "zhuyan");values.put("phone", "18739933");getContentResolver().insert(url, values);

执行这个操作后。数据库有一条数据 (1,1,zhuyan,18739933)
然后再执行:

ContentValues values = new ContentValues();values.put("id", 1);values.put("name", "sss");getContentResolver().insert(url, values);


这时候我们再去看数据库变成了(2,1,sss,null)
完成了根据id去判断这个insert是直接插入还是去对比替换。如果想要几个属性同时对比,建立索引的时候定义就好了

db.execSQL("DROP INDEX IF EXISTS "+INDEX_NAME);db.exeSQL("create unique index "+ INDEX_NAME+" on "+tableName+"(name,phone)");
这样就是通过对比name,phone  2个属性去判断2条数据是否一样

0 0
原创粉丝点击