3

コードをリファクタリングし、すべてのinsertステートメントをに置き換えていましたが、プリペアドステートメントの代わりにinsert or replace使用する次のメソッドを見つけました。db.insert()

public static void insertIntoTableByNameAndFieldsAndValues(
        String tableName, String[] fields, String[] values, Context c)
        throws FieldsAndValuesMismatchException, UnrecognizedTypeException   {

    DatabaseAbstractionLayer dal = new DatabaseAbstractionLayer(c);
    SQLiteDatabase db = dal.getWritableDatabase();

    ContentValues con = new ContentValues();

    if (fields.length != values.length)
        throw new FieldsAndValuesMismatchException(
                "fieldsString and values are not the same size");

    int fieldCount = fields.length;

    for (int i = 0; i < fieldCount; i++) {
        String[] fieldArr = fields[i].split(":");
        String value = values[i];
        if (fieldArr[1].equalsIgnoreCase("long")) {
            // long
            if(value.equalsIgnoreCase("null")){
                con.putNull(fieldArr[0]);
            }else{
                con.put(fieldArr[0],(long) Integer.parseInt(value));
            }
        } else if (fieldArr[1].equalsIgnoreCase("string") || fieldArr[1].equalsIgnoreCase("text")) {
            // string

            if(value.equalsIgnoreCase("null")){
                con.putNull(fieldArr[0]);
            }else{
                con.put(fieldArr[0], value);
            }


        }else if(fieldArr[1].equalsIgnoreCase("double")){
            //double

            if(value.equalsIgnoreCase("null")){
                con.putNull(fieldArr[0]);
            }else{
                con.put(fieldArr[0], Double.valueOf(value));
            }

        } else {
            throw new UnrecognizedTypeException(fieldArr[1]
                    + " is not string,text, long or double");
        }
    }

    db.insert(tableName, null, con);

 db.close();
}

コードを書き直して生のクエリを使用したくありません。競合が発生したときに行を置き換える方法はありますか?そうなると思いinsertWithOnConflict()ますが、良い例が見つかりませんでした。

4

1 に答える 1

15

うん、(BaseColumns._IDAndroidで使用される行識別子の標準名に従わない場合は、適切な名前に変更してください)。これで、必要な処理が実行されます。

db.insertWithOnConflict(tableName, BaseColumns._ID, v, 
        SQLiteDatabase.CONFLICT_REPLACE);

しかし-その方法は確かに多くの無意味なことをします。要するに、それはこれに要約することができます:

public static void insertIntoTableByNameAndFieldsAndValues(
    String tableName, String[] fields, String[] values, Context c)
    throws FieldsAndValuesMismatchException {

    if (fields.length != values.length) {
        throw new FieldsAndValuesMismatchException(
            "fields[] and values[] are not the same length");
    }
    ContentValues v = new ContentValues();
    // You really don't need to distinguish between integers, doubles
    // etc. etc. - SQLite is type agnostic, just dumping Strings from Java
    // will work just fine - the *only* point in converting stuff is to check
    // the format prior to inserts.
    // Using "null" as the null identifier is also pointless. Pass actual null
    // values instead - calling #putNull("somecolumn") is the same 
    // as #put("somecolumn", null)
    for (int i = 0; i < fields.length; i++) {
        v.put(fields[i], values[i]);
    }
    db.insertWithOnConflict(tableName, BaseColumns._ID, v, 
            SQLiteDatabase.CONFLICT_REPLACE);
}
于 2012-08-01T11:35:12.273 に答える