我的家園

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

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


            DBApiLayer.MyCollection 繼承了抽象類 DBCollection,具體實(shí)現(xiàn)了增刪改查操作。
          DBCollection 類的介紹可以參考之前的文章: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 方法,這兩個方法的實(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 ) );
                          }
                      }
          
                      // 是否更新對應(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 作為交互開始的信號
                          om.writeInt( 0 ); // reserved
          
                          // 輸出完整的 namespace
                          om.writeCString( _fullNameSpace );
          
                          // 將要輸出的對象寫入 OutMessage 
                          for ( ; cur<arr.length; cur++ ){
                              DBObject o = arr[cur];
                              om.putObject( o );
          
                              // 一次批量插入數(shù)據(jù)量的上限是 maxBsonObjectSize 的 4 倍
                              // 安全起見,這里使用 maxBsonObjectSize 的兩倍
                              if ( om.size() > 2 * maxsize ){
                                  // 超出一次批量插入的限制
                                  // 停止構(gòu)造 OutMessage,準(zhǔn)備進(jìn)入下一個循環(huán)
                                  cur++;
                                  break;
                              }
                          }
           
                          // 調(diào)用 DBTCPConnector 的 say 方法執(zhí)行寫入
                          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 方法獲得查詢結(jié)果
                      Response res = _connector.call( _db , this , query , null , 2 );
          
                      // 沒有結(jié)果
                      if ( res.size() == 0 )
                          return null;
                      
                      // 檢查錯誤
                      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 對象,它實(shí)現(xiàn)了 Iterator 接口,可以用于遍歷。
            next 方法和 hasNext 中都用到了 _advance 方法
                  // 獲取下一條記錄
                  public DBObject next(){
                      // 當(dāng)前 cursor 有下一條記錄,直接返回
                      if ( _cur.hasNext() ) {
                          return _cur.next();
                      }
          
                      // 沒有結(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;
                          
                          // 沒有結(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 作為交互開始的信號
                      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 );
                  }
          





          只有注冊用戶登錄后才能發(fā)表評論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 千阳县| 墨竹工卡县| 自治县| 沧州市| 阿城市| 景东| 阜平县| 麻城市| 延庆县| 汉寿县| 南开区| 张家口市| 华容县| 石渠县| 三河市| 铁力市| 宜春市| 青州市| 平阳县| 石河子市| 阳泉市| 禄劝| 百色市| 肇州县| 大安市| 平塘县| 天峨县| 浑源县| 衡东县| 迁西县| 邛崃市| 新兴县| 和龙市| 安仁县| 滦平县| 赤城县| 石首市| 遵义市| 石棉县| 岗巴县| 曲沃县|