我的家園

          我的家園
            DBAPILayer 繼承了抽象類(lèi) DB ,主要借助內(nèi)部類(lèi) DBApiLayer.MyCollection 實(shí)現(xiàn)具體的數(shù)據(jù)庫(kù)操作。
          DB 類(lèi)的介紹可以參考:http://xxing22657-yahoo-com-cn.iteye.com/blog/1291183

          借助 DBApiLayer.MyCollection 實(shí)現(xiàn)增刪改查


            DBApiLayer.MyCollection 繼承了抽象類(lèi) DBCollection,具體實(shí)現(xiàn)了增刪改查操作。
          DBCollection 類(lèi)的介紹可以參考之前的文章:http://xxing22657-yahoo-com-cn.iteye.com/blog/1255181

            增刪改查操作的方法聲明如下:
                  // 插入操作
                  protected WriteResult insert(DBObject[] arr, boolean shouldApply , com.mongodb.WriteConcern concern )
                  // 刪除操作
                  public WriteResult remove( DBObject o , com.mongodb.WriteConcern concern )
                  // 查找操作
                  Iterator<DBObject> __find( DBObject ref , DBObject fields , int numToSkip , int batchSize, int limit , int options )
                   // 更新操作
                  public WriteResult update( DBObject query , DBObject o , boolean upsert , boolean multi , com.mongodb.WriteConcern concern )
          

            這些操作都需要借助 DBTCPConnector 的 say 方法和 call 方法,這兩個(gè)方法的實(shí)現(xiàn)可以參考這篇文章:
            http://xxing22657-yahoo-com-cn.iteye.com/blog/1416331

            下面以 insert 和 _find 操作為例進(jìn)行分析
                  // 插入操作
                  protected WriteResult insert(DBObject[] arr, boolean shouldApply , com.mongodb.WriteConcern concern )
                      throws MongoException {
          
                      // 輸出跟蹤信息
                      if ( willTrace() ) {
                          for (DBObject o : arr) {
                              trace( "save:  " + _fullNameSpace + " " + JSON.serialize( o ) );
                          }
                      }
          
                      // 是否更新對(duì)應(yīng)的DBObject
                      if ( shouldApply ){
                          for ( int i=0; i<arr.length; i++ ){
                              DBObject o=arr[i];
                              apply( o );
                              _checkObject( o , false , false );
                              Object id = o.get( "_id" );
                              if ( id instanceof ObjectId ){
                                  ((ObjectId)id).notNew();
                              }
                          }
                      }
          
                      WriteResult last = null;
          
                      // 輸出 DBObject 到 Mongo 服務(wù)器
                      int cur = 0;
                      int maxsize = _mongo.getMaxBsonObjectSize();
                      while ( cur < arr.length ){
                          OutMessage om = new OutMessage( _mongo , 2002 );
           
                          // 以 0 作為交互開(kāi)始的信號(hào)
                          om.writeInt( 0 ); // reserved
          
                          // 輸出完整的 namespace
                          om.writeCString( _fullNameSpace );
          
                          // 將要輸出的對(duì)象寫(xiě)入 OutMessage 
                          for ( ; cur<arr.length; cur++ ){
                              DBObject o = arr[cur];
                              om.putObject( o );
          
                              // 一次批量插入數(shù)據(jù)量的上限是 maxBsonObjectSize 的 4 倍
                              // 安全起見(jiàn),這里使用 maxBsonObjectSize 的兩倍
                              if ( om.size() > 2 * maxsize ){
                                  // 超出一次批量插入的限制
                                  // 停止構(gòu)造 OutMessage,準(zhǔn)備進(jìn)入下一個(gè)循環(huán)
                                  cur++;
                                  break;
                              }
                          }
           
                          // 調(diào)用 DBTCPConnector 的 say 方法執(zhí)行寫(xiě)入
                          last = _connector.say( _db , om , concern );
                      }
                      
                      return last;
                  }
                  
                  // 查找操作
                  Iterator<DBObject> __find( DBObject ref , DBObject fields , int numToSkip , int batchSize, int limit , int options )
                      throws MongoException {
                      
                      if ( ref == null )
                          ref = new BasicDBObject();
                      
                      // 輸出跟蹤信息
                      if ( willTrace() ) trace( "find: " + _fullNameSpace + " " + JSON.serialize( ref ) );
           
                      // 構(gòu)造 OutMessage 
                      OutMessage query = OutMessage.query( _mongo , options , _fullNameSpace , numToSkip , chooseBatchSize(batchSize, limit, 0) , ref , fields );
          
                      // 調(diào)用 DBTCPConnector 的 call 方法獲得查詢(xún)結(jié)果
                      Response res = _connector.call( _db , this , query , null , 2 );
          
                      // 沒(méi)有結(jié)果
                      if ( res.size() == 0 )
                          return null;
                      
                      // 檢查錯(cuò)誤
                      if ( res.size() == 1 ){
                          BSONObject foo = res.get(0);
                          MongoException e = MongoException.parse( foo );
                          if ( e != null && ! _name.equals( "$cmd" ) )
                              throw e;
                      }
          
                      // 返回結(jié)果            
                      return new Result( this , res , batchSize, limit , options );
                  }
          


          借助 DBApiLayer.Result 遍歷結(jié)果


            DBApiLayer.MyCollection._find 方法返回的是 Result 對(duì)象,它實(shí)現(xiàn)了 Iterator 接口,可以用于遍歷。
            next 方法和 hasNext 中都用到了 _advance 方法
                  // 獲取下一條記錄
                  public DBObject next(){
                      // 當(dāng)前 cursor 有下一條記錄,直接返回
                      if ( _cur.hasNext() ) {
                          return _cur.next();
                      }
          
                      // 沒(méi)有結(jié)果,拋異常
                      if ( ! _curResult.hasGetMore( _options ) )
                          throw new RuntimeException( "no more" );
          
                     // 有結(jié)果,但不在當(dāng)前 cursor 中,取下一批數(shù)據(jù)
                      _advance();
          
                     // 遞歸調(diào)用
                      return next();
                  }
          
                  // 是否包含下一條記錄
                  public boolean hasNext(){
                      // 循環(huán)檢查
                      while ( true ){
                      // 當(dāng)前 cursor 有下一條記錄,直接返回 true
                          if ( _cur.hasNext() )
                              return true;
                          
                          // 沒(méi)有結(jié)果,返回 false
                          if ( ! _curResult.hasGetMore( _options ) )
                              return false;
          
                          // 有結(jié)果,但不在當(dāng)前 cursor 中,取下一批數(shù)據(jù)
                          _advance();
                      }
                  }
          
                  // 進(jìn)行到下一條記錄
                  private void _advance(){
          
                      if ( _curResult.cursor() <= 0 )
                          throw new RuntimeException( "can't advance a cursor <= 0" );
                      
                      OutMessage m = new OutMessage( _mongo , 2005 );
          
                      // 以 0 作為交互開(kāi)始的信號(hào)
                      m.writeInt( 0 ); 
           
                       // 輸出完整的 namespace
                      m.writeCString( _collection._fullNameSpace );
          
                      // 輸出數(shù)據(jù)大小
                      m.writeInt( chooseBatchSize(_batchSize, _limit, _numFetched) );
          
                      // 輸出當(dāng)前 cusor 的位置
                      m.writeLong( _curResult.cursor() );
          
                      // 借助 DBTCPConnector 執(zhí)行讀取操作
                      Response res = _connector.call( DBApiLayer.this , _collection , m , _host );
          
                     // 讀取下一條 
                     _numGetMores++;
          
                      // 初始化
                      init( res );
                  }
          





          只有注冊(cè)用戶(hù)登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 晋宁县| 岳西县| 青浦区| 邯郸县| 长顺县| 星子县| 斗六市| 湛江市| 通榆县| 方城县| 射洪县| 伽师县| 恩施市| 和平县| 安西县| 芒康县| 岑巩县| 岑溪市| 德州市| 怀宁县| 甘肃省| 合江县| 大宁县| 祁连县| 东至县| 湟中县| 云南省| 遵义县| 平山县| 安岳县| 方正县| 西林县| 南郑县| 柳林县| 珠海市| 凤翔县| 沈阳市| 河津市| 辽源市| 醴陵市| 襄城县|