原型:
long android.database.sqlite.SQLiteDatabase.insert(String table, String nullColumnHack, ContentValues values)
參數介紹:
table: 要插入資料的表的名稱
nullColumnHack:當values參數為空白或者裡面沒有內容的時候,我們insert是會失敗的(底層資料庫不允許插入一個空行),為了防止這種情況,我們要在這裡指定一個列名,到時候如果發現將要插入的行為空白行時,就會將你指定的這個列名的值設為null,然後再向資料庫中插入。
values:一個ContentValues對象,類似一個map.通過索引值對的形式儲存值。
這裡很多人會迷惑,nullColumnHack到底幹什麼用的,為什麼會出現呢。當我們不設定一列的時候,不都是資料庫給設為預設值嗎?很多欄位設定預設值也是null,這裡顯示的設定也是null,有什麼區別嗎,怎麼會顯示設定了之後就允許插入了呢?
其實在底層,各種insert方法最後都回去調用insertWithOnConflict方法,這裡我們粘貼出該方法的部分實現
[java] view plaincopy/** * General method for inserting a row into the database. * * @param table the table to insert the row into * @param nullColumnHack SQL doesn't allow inserting a completely empty row, * so if initialValues is empty this column will explicitly be * assigned a NULL value * @param initialValues this map contains the initial column values for the * row. The keys should be the column names and the values the * column values * @param conflictAlgorithm for insert conflict resolver * @return the row ID of the newly inserted row * OR the primary key of the existing row if the input param 'conflictAlgorithm' = * {@link #CONFLICT_IGNORE} * OR -1 if any error */ public long insertWithOnConflict(String table, String nullColumnHack, ContentValues initialValues, int conflictAlgorithm) { if (!isOpen()) { throw new IllegalStateException("database not open"); } // Measurements show most sql lengths <= 152 StringBuilder sql = new StringBuilder(152); sql.append("INSERT"); sql.append(CONFLICT_VALUES[conflictAlgorithm]); sql.append(" INTO "); sql.append(table); // Measurements show most values lengths < 40 StringBuilder values = new StringBuilder(40); Set<Map.Entry<String, Object>> entrySet = null; if (initialValues != null && initialValues.size() > 0) { entrySet = initialValues.valueSet(); Iterator<Map.Entry<String, Object>> entriesIter = entrySet.iterator(); sql.append('('); boolean needSeparator = false; while (entriesIter.hasNext()) { if (needSeparator) { sql.append(", "); values.append(", "); } needSeparator = true; Map.Entry<String, Object> entry = entriesIter.next(); sql.append(entry.getKey()); values.append('?'); } sql.append(')'); } else { sql.append("(" + nullColumnHack + ") "); values.append("NULL"); }
這裡我們可以看到,當我們的ContentValues類型的資料initialValues為null,或者size<=0時,就會再sql語句中添加nullColumnHack的設定。我們可以想象一下,如果我們不添加nullColumnHack的話,那麼我們的sql語句最終的結果將會類似insert into tableName()values();這顯然是不允許的。而如果我們添加上nullColumnHack呢,sql將會變成這樣,insert into
tableName (nullColumnHack)values(null);這樣很顯然就是可以的。
下面附上插入操作的方法代碼:
public void insert(String name, String address, String type, String notes) {ContentValues cv=new ContentValues();cv.put("name", name);cv.put("address", address);cv.put("type", type);cv.put("notes", notes);getWritableDatabase().insert("restaurants", "name", cv);}