关于ContentProvider 使用replace

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条数据是否一样

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值