在上一篇博客[《打造android ORM框架opendroid(三)——持久化數據》](http://blog.csdn.net/qibin0506/article/details/42872361)中,我們感受到了opendroid保存數據的流程,今天的博客我們來順一下opendroid是如何刪除數據的。
還記得我們在第一篇博客[《打造android ORM框架opendroid(一)——ORM框架的使用》](http://blog.csdn.net/qibin0506/article/details/42736807)中介紹過opendroid的使用,先來回顧一下怎么利用opendroid來刪除數據吧。
~~~
int?length?=?OpenDroid.delete(Student.class,?1,?2,?3);??????
System.out.println(length);????
~~~
還有一種刪除數據的方式是使用where條。
~~~
int?length?=?OpenDroid.delete(Student.class,?"_id>?",?"5");??????
System.out.println(length);??
~~~
opendroid就這么兩種刪除數據的方式,但這兩種方式已經可以適合大部分的需求了。
上面是回顧了一下opendroid的使用,但是我們今天的主題是了解opendroid是如何從數據庫中把數據刪除的。
所以...老規矩,首先定位到
` OpenDroid.delete(Student.class,?1,?2,?3);????`
從最簡單開始入手吧!
~~~
/**??
?*?刪除數據??
?*?@param?klass?要刪除的表對應的class??
?*?@param?ids?數據的ids??
?*?@return?影響行數??
?*/????
public?static?extends?OpenDroid>?int?delete(Class?klass,?int...?ids)?{????
????if(ids.length?==?0)?{????
????????return?delete(klass,?null,?null);????
????}????
????????????
????StringBuilder?builder?=?new?StringBuilder("_id?in?(");????
????String[]?whereArgs?=?new?String[ids.length];????
????buildIn(builder,?whereArgs,?ids);????
????????????
????return?delete(klass,?builder.toString(),?whereArgs);????
}???
~~~
根據id刪除的這個方法并不長,我們一句一句來分析一下。
首先8~10行,是一個判斷如果沒有設置id,則調用一個靜態的delete方法,這個delete方法我們稍候去看,現在我們接著往下走代碼。
12行,用了一個StringBuilder來初始化一個in語句,從這里我們可能已經清楚,使用這個delete方法刪除數據其實就是使用了sql語句的in操作。
13行,new了一個String類型的數組,數組的長度正好是ids的長度,為下面組件in語句做準備。
14行,我們調用了buildIn方法來構建一個in語句。
15行,直接調用了一個重載的delete的方法去刪除數據,這里提一下,這個delete方法和我們上面if語句中調用的delete方法是同一個。
下面我們再來看看buildIn這個方法吧。
~~~
/**??
?*?組裝IN語句??
?*?@param?builder?in語句??
?*?@param?whereArgs?in的內容??
?*?@param?ids?要拼裝的ids??
?*/????
private?static?void?buildIn(StringBuilder?builder,?String[]?whereArgs,????
????????int...?ids)?{????
????if(ids.length?>?1)?{????
????????for(int?i=0;i1;i++)?{????
????????????whereArgs[i]?=?String.valueOf(ids[i]);????
????????????builder.append("?,");????
????????}????
????}????
????????????
????whereArgs[ids.length?-?1]?=?String.valueOf(ids[ids.length?-?1]);????
????builder.append("?)");????
}??
~~~
縱觀整個buildIn方法也沒什么難點,這里的作用就是拼裝一個 _id in(?,?,?)這樣形式的語句,并將ids放到上面我們初始化的那個String數據中,這樣我們是不是就已經準備好了sql預處理中where的條件和條件的參數了呢?
當然這里還有兩點可能感到迷惑的:
1、該方法為什么沒有返回值? 這種寫法可能不是很常見,就是將返回值以參數的形式傳遞進來,大家都知道java的參數傳遞是按引用傳遞,所以只要不改變該參數指向地址,在該方法中對參數內容的修改是會影響調用者的。
2、for循環中為什么是ids.length-1?因為我們需要的是(?,?,?)這樣的形式,最后一個?后是沒有“,”的,所以我們需要先拼裝前length-1個,然后在循環外面進行了最后的收尾工作。
這里可能又會有朋友注意到,最后的收尾是在if外面進行的,這里是不是寫錯了? 這里是沒有錯的! 請看if的條件是什么!
分析完buildIn后,我們再返回那個delete方法中,最后一句是調用了另一個delete方法,至于參數,大家肯定已經清楚參數的值了。
下面再來看看這個重載的delete方法吧。
~~~
/**??
?*?刪除數據??
?*?@param?klass?要刪除的表對應的class??
?*?@param?where?where條件??
?*?@param?whereArgs?where條件的參數??
?*?@return?影響行數??
?*/????
public?static?extends?OpenDroid>?int?delete(Class?klass,?String?where,????
????????String...?whereArgs)?{????
????String?tableName?=?klass.getSimpleName();????
????return?CRUD.delete(tableName,?where,?whereArgs,?sSqliteDatabase);????
}??
~~~
哈哈,only兩行代碼,而且我們也驚奇的發現,這個方法也是我們上面第二種刪除的方式,太好了,兩種刪除方式最后還是會在同一個方法中碰面!
如此簡單,怎么下手呢? 第1行代碼獲取了klass的類名,這里代表的當然是我們刪除操作的表明了。
下一行中我們又去調用了CRUD.delete方法,那么我們跟進代碼,去看看CRUD.delete吧。
~~~
/**??
?*?刪除數據??
?*?@param?tableName?表名??
?*?@param?where?where條件??
?*?@param?whereArgs?where條件的參數??
?*?@param?db????數據庫??
?*?@return?影響行數??
?*/????
protected?static?extends?OpenDroid>?int?delete(String?tableName,?String?where,????
????????String[]?whereArgs,?SQLiteDatabase?db)?{????
????int?count?=?db.delete(tableName,?where,?whereArgs);????
????return?count;????
}??
~~~
又是兩行代碼!
首先來看看參數吧,第一個參數是要操作的表名,第二個參數是where條件,第三個參數是where條件的參數,第四個參數當然是我們操作數據庫的句柄了。
在代碼體中,第一句就去調用了android原生的delete操作去根據條件刪除數據,返回值是刪除的條目個數,緊接著返回該個數,CRUD.delete方法執行完畢!
這個刪除的條目個數會再次最多經過兩次返回,最終返回到我們的業務邏輯中。
最后,我們來回顧一下這個流程吧。
1、我們的代碼調用OpenDroid.delete方法
2、不管調用哪個重載的OpenDroid.delete方法,最后都會來到使用條件刪除的那個delete方法
3、使用id刪除,無非就是根據傳入的id和id個數來組件一個SQL的in語句
4、最后,在CRUD的delete方法中完成了數據的刪除,并返回影響行數。
opendroid的刪除操作我們已經順了一遍,看起來挺高端的,一看源碼是不是感覺如此簡單?
到現在為止,我們已經順完了opendroid的插入數據和刪除數據,在接下來的博客中,還會繼續完成opendroid更新數據和查詢數據的代碼。