一、發現問題
先看兩種方法插入數據
- public void save(Person p)
- {
- SQLiteDatabase db = dbHelper.getWritableDatabase();
- db.execSQL("insert into person(name,phone) values (?,?)", new Object[] { p.getName(), p.getPhone() });
- db.close();
- }
- public void save(Person p)
- {
- SQLiteDatabase db = dbHelper.getWritableDatabase(); // 取得數據庫操作實例
- ContentValues values = new ContentValues();
- values.put("name", p.getName());
- values.put("phone", p.getPhone());
- db.insert("person", "name", values);
- db.close();
- }
這兩種方法可讀性都比較好,但我們注意到db.insert("person", "name", values);操作中有一個name字段是什么意思呢?
二、解決問題
insert的一種構造方法
- public long insert (String table, String nullColumnHack, ContentValues values)
table
要插入數據的表的名稱
values
ContentValues對象,類似一個map通過鍵值對的形式存儲值。
nullColumnHack
當values參數為空或者里面沒有內容的時候,insert是會失敗的(底層數據庫不允許插入一個空行),為了防止這種情況,要在這里指定一個列名,到時候如果發現將要插入的行為空行時,就會將你指定的這個列名的值設為null,然后再向數據庫中插入。通過觀察源碼的insertWithOnConflict方法可以看到當ContentValues類型的數據initialValues為null或size<=0時,就會在sql語句中添加nullColumnHack的設置。
若不添加nullColumnHack則sql語句最終的結果將會類似insert into tableName()values();這是不允許的。
若添加上nullColumnHack則sql語句將會變成insert into tableName (nullColumnHack)values(null);這是可以的。
參考地址:http://mofan.iteye.com/blog/1412262