Android源碼分析------SQLiteDatabase(1)

看了SQLiteDatabase的replace接口的源碼,感受寫的很好,有些能夠借鑑的地方,記錄以下:java

    public long replace(String table, String nullColumnHack, ContentValues initialValues) {
        try {
            return insertWithOnConflict(table, nullColumnHack, initialValues,
                    CONFLICT_REPLACE);   //最後一個參數是爲了指明靜態數組的某個index值,沒有處理空指針
        } catch (SQLException e) {
            Log.e(TAG, "Error inserting " + initialValues, e);     //異常時,以Log.e打印出來
            return -1;                 //異常時返回-1
        }
    }

    public long insertWithOnConflict(String table, String nullColumnHack,
            ContentValues initialValues, int conflictAlgorithm) {
        acquireReference();
        try {
            StringBuilder sql = new StringBuilder();      //sql的組裝採用StringBuilder
            sql.append("INSERT");
            sql.append(CONFLICT_VALUES[conflictAlgorithm]);   //此處組裝的字符串以靜態數據中的某個值
            sql.append(" INTO ");
            sql.append(table);
            sql.append('(');

            Object[] bindArgs = null;
            int size = (initialValues != null && initialValues.size() > 0)
                    ? initialValues.size() : 0;             //獲取列表或者數組的大小能夠用這種方式
            if (size > 0) {
                bindArgs = new Object[size];
                int i = 0;
                for (String colName : initialValues.keySet()) {
                    sql.append((i > 0) ? "," : "");            //組裝代碼時,逗號能夠用這種語句組裝
                    sql.append(colName);
                    bindArgs[i++] = initialValues.get(colName);
                }
                sql.append(')');
                sql.append(" VALUES (");
                for (i = 0; i < size; i++) {
                    sql.append((i > 0) ? ",?" : "?");
                }
            } else {
                sql.append(nullColumnHack + ") VALUES (NULL");     //空指針的處理
            }
            sql.append(')');

            SQLiteStatement statement = new SQLiteStatement(this, sql.toString(), bindArgs);
            try {
                return statement.executeInsert();
            } finally {
                statement.close();
            }
        } finally {
            releaseReference();
        }
    }

    SQLiteDatabase的replace接口組裝了SQL語句的insert or replace功能,有不少值得借鑑的地方:android

一、SQLiteDatabase的不一樣接口,好比insert、replace等,都調用到一個具體實現的方法insertWithOnConflict,作到接口與實現的分離;sql

二、在接口中沒有對空指針進行處理,在具體實現的方法中對參數進行了處理。第一個參數table,沒有進行空指針判斷,由於表名是null也是能夠的,nullColumnHack和initialValues的空值也有相應處理數組

三、異常時,android中要用Log.e打印出來;app

四、有long型返回值時,能夠用-1做爲異常時的返回值;ui

五、sql數組的組裝採用的是StringBuilder;this

六、在處理列表或者數組類型的對象時,常常要進行null和大小爲0的判斷,能夠參照這種方式寫:spa

 int size = (initialValues != null && initialValues.size() > 0)
                    ? initialValues.size() : 0;

七、組裝代碼時,常常會遇到用逗號或者其餘符號進行分隔組裝的問題,能夠採用以下方式:
指針

sql.append((i > 0) ? "," : "");

八、return與finally的關係:code

 try {
     return statement.executeInsert();
 } finally {
     statement.close();
 }

  以上代碼的執行順序是:

  1) statement.executeInsert()

  2) statement.close()

  3) return

  就是說,代碼順序地執行着,走着走着,走到statement.executeInsert()執行完時,發現了return,原來本身快over了,臨死前,它去找finally,讓finally把事情作完。等finally作完,執行return返回了。

相關文章
相關標籤/搜索