<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                在上一篇博客[《打造android ORM框架opendroid(五)——數據更新的實現》](http://blog.csdn.net/qibin0506/article/details/43148523)??我們介紹了opendroid數據更新的流程,也就在上次,我們OpenDroid類中的所有操作都介紹完了, 那查詢操作呢?不是在OpenDroid中?查詢操作是在OpenDroid中,不過是以內部類的形式呈現的。 還是來看看如果使用opendroid查詢數據吧。 ` OpenDroid.query.find(Student.class)??` ` OpenDroid.query.columns("stuName").where("_id>?",?"1").limit(1,?4).order("_id?DESC").find(Student.class);????` 這是opendroid提供的查詢方法,也是最常見的級聯查詢,了解其他ORM框架的朋友們肯定對此不陌生吧,但是,看第二段代碼,我們比傳統的級聯操作多了一個方法columns(),該方法是設置要查詢的字段。 好了, 進入我們今天的重點,通過上面代碼,我們發現是通過調用了OpenDroid的一個靜態字段query的各個方法去組合查詢的。我們來看看query。 ` public?static?Query?query?=?new?Query();??` 在OpenDroid中這個Query類型的字段,并且在定義的時候就去實例化了。我們再來看看Query這個內部類。 ~~~ ?/**?? ?*?查詢?? ?*?@author?qibin?? ?*/???? public?static?class?Query?{???? ????private?String[]?mCocumns?=?null;??//?要查詢的字段???? ????private?String?mWhere?=?null;???//?查詢的條件???? ????private?String[]?mWhereArgs?=?null;?//?查詢的條件的參數???? ????private?String?mOrder?=?null;?//?order語句???? ????private?String?mLimit;?//?limit語句???? ???????????? ????/**?? ?????*?設置查詢的字段?? ?????*?@param?columns?要查詢的字段?? ?????*?@return?Query對象?? ?????*/???? ????public?Query?columns(String...?columns)?{???? ????????mCocumns?=?columns;???? ????????return?this;???? ????}???? ???????????? ????/**?? ?????*?設置查詢的where條件?? ?????*?@param?where?where條件?? ?????*?@param?whereArgs?where參數?? ?????*?@return?Query對象?? ?????*/???? ????public?Query?where(String?where,?String...?whereArgs)?{???? ????????mWhere?=?where;???? ????????mWhereArgs?=?whereArgs;???? ????????return?this;???? ????}???? ???????? ????/**?? ?????*?設置查詢的order?? ?????*?@param?order?order語句?? ?????*?@return?Query對象?? ?????*/???? ????public?Query?order(String?order)?{???? ????????mOrder?=?order;???? ????????return?this;???? ????}???? ???????????? ????/**?? ?????*?設置查詢的limit?? ?????*?@param?limit?limit語句?? ?????*?@return?Query對象?? ?????*/???? ????public?Query?limit(int...?limit)?{???? ????????StringBuilder?builder?=?new?StringBuilder();???? ????????builder.append(limit[0]);???? ???????????????? ????????if(limit.length?==?2)?{???? ????????????builder.append(",").append(limit[1]);???? ????????}???? ???????????????? ????????mLimit?=?builder.toString();???? ???????????????? ????????return?this;???? ????}???? ???????????? ????/**?? ?????*?查詢?? ?????*?@param?klass?映射的bean?? ?????*?@return?查詢結果?? ?????*/???? ????public?extends?OpenDroid>?List?find(Class?klass)?{???? ????????return?CRUD.query(klass,?mCocumns,?mWhere,?mWhereArgs,????? ????????????????mOrder,?mLimit,?sSqliteDatabase);???? ????}???? ???????????? ????/**?? ?????*?根據id查詢數據?? ?????*?@param?klass?klass?映射的bean?? ?????*?@param?id?要查詢數據的id?? ?????*?@return??查詢結果?? ?????*/???? ????public?extends?OpenDroid>?T?find(Class?klass,?int?id)?{???? ????????List?result?=?CRUD.query(klass,?mCocumns,?"_id=?",????? ????????????????new?String[]?{?String.valueOf(id)?},?null,?"1",???? ????????????????sSqliteDatabase);???? ????????return?result.size()?>?0???result.get(0)?:?null;???? ????}???? ???????????? ????public?extends?OpenDroid>?List?find(Class?klass,?int...?ids)?{???? ????????StringBuilder?builder?=?new?StringBuilder("_id?in?(");???? ????????String[]?whereArgs?=?new?String[ids.length];???? ????????buildIn(builder,?whereArgs,?ids);???? ???????????????? ????????return?CRUD.query(klass,?mCocumns,?builder.toString(),?whereArgs,????? ????????????????mOrder,?mLimit,?sSqliteDatabase);???? ????}???? ???????????? ????/**?? ?????*?使用sql語句查詢?? ?????*?@param?sql?sql語句?? ?????*?@param?selectionArgs?預編譯參數?? ?????*?@return?? ?????*/???? ????public?Cursor?queryBySql(String?sql,?String[]?selectionArgs)?{???? ????????return?sSqliteDatabase.rawQuery(sql,?selectionArgs);???? ????}???? }?? ~~~ 這個內部類中,上來咔咔咔列出了5個字段,注釋已經說的很清楚了,其實就是組合查詢語句用的。 往下看,我們看到了熟悉的方法,這些都是在上面介紹的時候用到的,并且一些方法的返回值都是this,大家應該很清楚,我們要級聯操作嘛,就必須要返回當前對象。 好吧,第一個方法 ~~~ /**?? ?*?設置查詢的字段?? ?*?@param?columns?要查詢的字段?? ?*?@return?Query對象?? ?*/???? public?Query?columns(String...?columns)?{???? ????mCocumns?=?columns;???? ????return?this;???? }???? ~~~ 很簡單,就是把要查詢的字段保存起來,然后返回當前對象。 ~~~ /**?? ?*?設置查詢的where條件?? ?*?@param?where?where條件?? ?*?@param?whereArgs?where參數?? ?*?@return?Query對象?? ?*/???? public?Query?where(String?where,?String...?whereArgs)?{???? ????mWhere?=?where;???? ????mWhereArgs?=?whereArgs;???? ????return?this;???? }??? ~~~ where方法也很簡單,保存了where條件和where條件的參數。 ~~~ /**?? ?*?設置查詢的order?? ?*?@param?order?order語句?? ?*?@return?Query對象?? ?*/???? public?Query?order(String?order)?{???? ????mOrder?=?order;???? ????return?this;???? }??? ~~~ 好吧,一樣的邏輯(哪里有邏輯!!!) ~~~ /**?? ?*?設置查詢的limit?? ?*?@param?limit?limit語句?? ?*?@return?Query對象?? ?*/???? public?Query?limit(int...?limit)?{???? ????StringBuilder?builder?=?new?StringBuilder();???? ????builder.append(limit[0]);???? ???????????????? ????if(limit.length?==?2)?{???? ????????builder.append(",").append(limit[1]);???? ????}???? ???????????????? ????mLimit?=?builder.toString();???? ???????????????? ????return?this;???? }??? ~~~ 設置limit, 這個方法還算長一點,但是一點內容也沒有,就是組合一個limit語句,不過這里做了一個數組長度的判斷,主要是為了適配limit 1和limit 1,2這兩種方式。 ~~~ /**?? ?*?查詢?? ?*?@param?klass?映射的bean?? ?*?@return?查詢結果?? ?*/???? public?extends?OpenDroid>?List?find(Class?klass)?{???? ????return?CRUD.query(klass,?mCocumns,?mWhere,?mWhereArgs,?mOrder,?mLimit,?sSqliteDatabase);???? }?? ~~~ 這個查詢方法直接調用了CRUD.query并返回它的返回值,相信大家看到CRUD肯定很熟悉了,我們定位到CRUD中query這個方法看看吧。 ~~~ /**?? ?*?查詢數據?? ?*?@param?klass?要映射的類?? ?*?@param?columns?查詢的字段,?null?取所有?? ?*?@param?where?where條件,?null?忽略條件?? ?*?@param?whereArgs?where的參數,?null無參數?? ?*?@param?order?order語句,?null忽略order?by?? ?*?@param?limit?limit語句,?null忽略limit?? ?*?@param?db????數據庫句柄?? ?*?@return?查詢后的數據?? ?*/???? protected?static?extends?OpenDroid>?List?query(Class?klass,?String[]?columns,????? ????????String?where,?String[]?whereArgs,?String?order,?String?limit,?SQLiteDatabase?db)?{???? ????List?resultList?=?new?ArrayList();?//?存放結果???? ????String?tableName?=?klass.getSimpleName();?//?獲取類名(表名)???? ????Cursor?cursor?=?null;???? ???????????? ????try?{???? ????????cursor?=?db.query(tableName,?columns,?where,?whereArgs,?null,?null,?order,?limit);???? ????????foreachCursor(klass,?cursor,?resultList);???? ????}?catch?(Exception?e)?{???? ????????e.printStackTrace();???? ????}?finally?{???? ????????if(cursor?!=?null)?{???? ????????????cursor.close();???? ????????}???? ????}???? ???????????? ????return?resultList;???? }?? ~~~ 參數有點多,那么我們就從參數說起。 第一個參數是一個Class,應該很清晰了,我們要根據它來獲取要查詢的表明,接下來的一系列就是要查詢的字段,條件,order語句,limit語句,最后一個是我們操作的數據庫句柄。 繼續看代碼,首先new類一個ArrayList,并且獲取了要操作的表名,接下來在try中,直接調用了android原生api的query返回一個Cursor對象,這就是我們查詢的結果。接下來調用foreachCursor方法,將結果遍歷到剛開new的那個ArrayList中,查詢操作完畢! 那么我們來看看foreachCursor方法。 ~~~ /**?? ?*?遍歷數據庫游標?? ?*?@param?klass?要映射的類?? ?*?@param?cursor?要遍歷的游標?? ?*?@param?resultList?存放返回的結果?? ?*?@throws?InstantiationException?? ?*?@throws?IllegalAccessException?? ?*/???? private?static?extends?OpenDroid>?void?foreachCursor(Class?klass,???? ????????Cursor?cursor,?List?resultList)?throws?InstantiationException,???? ????????IllegalAccessException?{???? ????T?t;?//?反射出的實例???? ????String?columnName;?//?數據庫字段名???? ????String?methodName;?//?方法名???? ????Method?m;?//?反射出的方法???? ???????????? ????for(cursor.moveToFirst();!cursor.isAfterLast();cursor.moveToNext())?{???? ????????t?=?klass.newInstance();??//?通過反射進行實例化???? ????????for(int?i=0;i ????????????columnName?=?cursor.getColumnName(i);?//?獲取數據庫字段名???? ????????????try?{???? ????????????????switch?(cursor.getType(i))?{???? ????????????????case?Cursor.FIELD_TYPE_INTEGER:???? ????????????????????//?如果字段名是_id的話,?對應的方法是setId???? ????????????????????methodName?=?columnName.equals("_id")???"setId"?:????? ????????????????????????getMethodName(cursor.getColumnName(i));???? ????????????????????m?=?klass.getMethod(methodName,?int.class);?//?反射出方法???? ????????????????????m.invoke(t,?cursor.getInt(i));?//?執行方法???? ????????????????????break;???? ????????????????case?Cursor.FIELD_TYPE_FLOAT:???? ????????????????????methodName?=?getMethodName(cursor.getColumnName(i));???? ????????????????????m?=?klass.getMethod(methodName,?float.class);???? ????????????????????m.invoke(t,?cursor.getFloat(i));???? ????????????????????break;???? ????????????????default:???? ????????????????????methodName?=?getMethodName(cursor.getColumnName(i));???? ????????????????????m?=?klass.getMethod(methodName,?String.class);???? ????????????????????m.invoke(t,?cursor.getString(i));???? ????????????????????break;???? ????????????????}???? ????????????}catch(Exception?e)?{???? ????????????????e.printStackTrace();???? ????????????}???? ????????}???? ????????resultList.add(t);???? ????}???? }?? ~~~ 又是一個巨長的... 我們來一點點分析吧。首先看參數,前兩個不用說,最后一個參數是要存放我們遍歷的結果的,這種方式在以前的博客中也有介紹過。 大體看一下這個方法,雖然很長,但是不難,switch case中的語句只需要了解一個剩下的就都了解了。 首先定義了4個變量,先有點印象。接著一個for循環,for循環也是做android的很熟悉的,就是去遍歷游標,如果你還不清楚這里,建議去看看android原生api。 18行,我們獲取Class的實例,實例化主要是為將表中的數據查詢保存到我們的java bean中。 接下來19行,又是一個for循環,這個循環是循環的什么呢? 恩,這里是循環的該行的所有字段。 20行,獲取當前index的字段名。 接下來一個switch case,這里我們只去觀察第一個case語句中的代碼。 25行是去拼湊一個setter,不過這個有點特殊,有一個二目運算符,我先解釋一下這是為什么,還記得我曾經提到過id是opendroid默認添加的,而不需要我們去定義bean字段嗎? 而且我們在分析創建數據庫的源碼中也看到了自動創建_id字段的代碼,但是現在就有一個問題了。 我們沒有id字段,id怎么放bean中呢? 所以在OpenDroid類中我強制定義了一個id字段,而且在使用的過程中,你也應該發現你的bean實例會有一個getId和setId的方法。看源碼來證明一下吧: ~~~ private?int?id;???? public?int?getId()?{???? ????return?id;???? }???? ???? public?void?setId(int?id)?{???? ????this.id?=?id;???? }?? ~~~ 知道了這一點,我們再來理解這句話,如果查詢的是_id字段,那么我們就去調用setId這個方法,否則就去調用getMethodName()根據當前數據庫中的字段名拼湊出一個setter方法。 好吧,接著分析代碼,27~28行,反射出我們拼湊的這個方法,并通過invoke去執行該方法,到這里,比如我們要獲取stuName字段,那么Student.stuName就有值了。 在獲取完當前行數據后,46行將生成的這個對象添加到ArrayList中保存起來。 總之,該方法的作用就是通過反射去實例化對應的類,并通過類中的setter方法設置值。 這里面還用到了一個getMethodName()方法,這個方法很簡單,就是根據數據庫字段名拼湊一個setXXX方法。 ~~~ /**?? ?*?根據字段名構建方法名?? ?*?@param?columnName?? ?*?@return?? ?*/???? public?static?String?getMethodName(String?columnName)?{???? ????String?methodName?=?columnName;???? ????methodName?=?Character.toUpperCase(methodName.charAt(0))?+?methodName.substring(1);???? ????methodName?=?"set"?+?methodName;???? ???????????? ????return?methodName;???? }??? ~~~ 很簡單,不多說了,唯一需要注意的是第8行,意思是將字段名的首字母大寫。 至此,一個find方法的流程就分析完了,其實剩下的find方法都是調用了同一個CRUD.query方法去查詢的。 ~~~ /**?? ?*?根據id查詢數據?? ?*?@param?klass?klass?映射的bean?? ?*?@param?id?要查詢數據的id?? ?*?@return??查詢結果?? ?*/???? public?extends?OpenDroid>?T?find(Class?klass,?int?id)?{???? ????List?result?=?CRUD.query(klass,?mCocumns,?"_id=?",????? ????????????new?String[]?{?String.valueOf(id)?},?null,?"1",???? ????????????sSqliteDatabase);???? ????return?result.size()?>?0???result.get(0)?:?null;???? }??? ~~~ 這個方法調用了CRUD.query方法去查詢的,只是我們確定了條件。 ~~~ public?extends?OpenDroid>?List?find(Class?klass,?int...?ids)?{???? ????StringBuilder?builder?=?new?StringBuilder("_id?in?(");???? ????String[]?whereArgs?=?new?String[ids.length];???? ????buildIn(builder,?whereArgs,?ids);???? ???????????????? ????return?CRUD.query(klass,?mCocumns,?builder.toString(),?whereArgs,????? ????????????mOrder,?mLimit,?sSqliteDatabase);???? }??? ~~~ 這個方法同樣的原理,只需要是多個id,只要是多個id的,我們都是通過in語句去實現的,所以調用了buildIn方法去拼湊了一個in語句,剩下的和其他的find方法一樣。 好啦,至此為止,opendroid的查詢操作我們也介紹完了,也就是opendroid的所有CRUD操作有順了一遍,那是不是opendroid所有功能都完了呢? 當然不是,還有我們的數據庫升級方案呢! 所以下篇博客將會介紹opendroid的數據庫升級方案! 最后是opendroid的開源地址:[http://git.oschina.net/qibin/OpenDroid](http://git.oschina.net/qibin/OpenDroid)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看