原博文地址:http://blog.csdn.net/jason0539/article/details/9977175
原型:
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方法,这里我们粘贴出该方法的部分实现:
1 [java] view plaincopy/** 2 * General method for inserting a row into the database. 3 * 4 * @param table the table to insert the row into 5 * @param nullColumnHack SQL doesn't allow inserting a completely empty row, 6 * so if initialValues is empty this column will explicitly be 7 * assigned a NULL value 8 * @param initialValues this map contains the initial column values for the 9 * row. The keys should be the column names and the values the 10 * column values 11 * @param conflictAlgorithm for insert conflict resolver 12 * @return the row ID of the newly inserted row 13 * OR the primary key of the existing row if the input param 'conflictAlgorithm' = 14 * {@link #CONFLICT_IGNORE} 15 * OR -1 if any error 16 */ 17 public long insertWithOnConflict(String table, String nullColumnHack, 18 ContentValues initialValues, int conflictAlgorithm) { 19 if (!isOpen()) { 20 throw new IllegalStateException("database not open"); 21 } 22 23 // Measurements show most sql lengths <= 152 24 StringBuilder sql = new StringBuilder(152); 25 sql.append("INSERT"); 26 sql.append(CONFLICT_VALUES[conflictAlgorithm]); 27 sql.append(" INTO "); 28 sql.append(table); 29 // Measurements show most values lengths < 40 30 StringBuilder values = new StringBuilder(40); 31 32 Set<Map.Entry<String, Object>> entrySet = null; 33 if (initialValues != null && initialValues.size() > 0) { 34 entrySet = initialValues.valueSet(); 35 Iterator<Map.Entry<String, Object>> entriesIter = entrySet.iterator(); 36 sql.append('('); 37 38 boolean needSeparator = false; 39 while (entriesIter.hasNext()) { 40 if (needSeparator) { 41 sql.append(", "); 42 values.append(", "); 43 } 44 needSeparator = true; 45 Map.Entry<String, Object> entry = entriesIter.next(); 46 sql.append(entry.getKey()); 47 values.append('?'); 48 } 49 50 sql.append(')'); 51 } else { 52 sql.append("(" + nullColumnHack + ") "); 53 values.append("NULL"); 54 }
这里我们可以看到,当我们的ContentValues类型的数据initialValues为null,或者size<=0时,就会再sql语句中添加nullColumnHack的设置。我们可以想象一下,如果我们不添加nullColumnHack的话,那么我们的sql语句最终的结果将会类似insert into tableName()values();这显然是不允许的。而如果我们添加上nullColumnHack呢,sql将会变成这样,insert into tableName (nullColumnHack)values(null);这样很显然就是可以的。