Sqlite insert方法nullColumnHack字段的含义

利用数据库对象SQLiteDatabase对数据库进行增删改查操作。

    这里要强调一点,无论我们怎么获得的数据库连接,我们可以看到,我们最后都是为了获得一个SQLiteDatabase对象,而我们的所以增删改查方法便都是通过这个对象来实现的。

 

增加数据:

 

Sqlite insert方法nullColumnHack字段的含义_第1张图片

 

 参数介绍:

table 要插入数据的表的名称

values:一个ContentValues对象,类似一个map.通过键值对的形式存储值。

conflictAlgon:冲突解决方案。例如当数据表主键的唯一性检测出错的时候,就会按照该值设定的值进行处理。

nullColumnHack:当values参数为空或者里面没有内容的时候,我们insert是会失败的(底层数据库不允许插入一个空行),为了防止这种情况,我们要在这里指定一个列名,到时候如果发现将要插入的行为空行时,就会将你指定的这个列名的值设为null,然后再向数据库中插入。

 

(这里很多人会迷惑,nullColumnHack到底干什么用的,为什么会出现呢。当我们不设定一列的时候,不都是数据库给设为默认值吗?很多字段设置默认值也是null,这里显示的设置也是null,有什么区别吗,怎么会显示设置了之后就允许插入了呢?笔者为了找到原因,我去查看了源代码)

其实在底层,各种insert方法最后都回去调用insertWithOnConflict方法,这里我们粘贴出该方法的部分实现

 

 

[java] view plaincopy
  1. /** 
  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);这样很显然就是可以的。

你可能感兴趣的:(Sqlite insert方法nullColumnHack字段的含义)