您的位置:首页 > 编程语言 > PHP开发

关于ContentProvider 使用replace

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

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

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

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

@Override
public 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条数据是否一样
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: