`
裴小星
  • 浏览: 265326 次
  • 性别: Icon_minigender_1
  • 来自: 北京
博客专栏
8ccf5db2-0d60-335f-a337-3c30d2feabdb
Java NIO翻译
浏览量:27829
F3e939f0-dc16-3d6e-8c0b-3315c810fb91
PureJS开发过程详解
浏览量:74162
07a6d496-dc19-3c71-92cf-92edb5203cef
MongoDB Java ...
浏览量:62963
社区版块
存档分类
最新评论

MongoDB Java Driver 源码分析(7):com.mongodb.DBAPILayer

阅读更多
  DBAPILayer 继承了抽象类 DB ,主要借助内部类 DBApiLayer.MyCollection 实现具体的数据库操作。
DB 类的介绍可以参考:http://xxing22657-yahoo-com-cn.iteye.com/blog/1291183

借助 DBApiLayer.MyCollection 实现增删改查


  DBApiLayer.MyCollection 继承了抽象类 DBCollection,具体实现了增删改查操作。
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 方法,这两个方法的实现可以参考这篇文章:
  http://xxing22657-yahoo-com-cn.iteye.com/blog/1416331

  下面以 insert 和 _find 操作为例进行分析
        // 插入操作
        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 ) );
                }
            }

            // 是否更新对应的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 服务器
            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 );

                    // 一次批量插入数据量的上限是 maxBsonObjectSize 的 4 倍
                    // 安全起见,这里使用 maxBsonObjectSize 的两倍
                    if ( om.size() > 2 * maxsize ){
                        // 超出一次批量插入的限制
                        // 停止构造 OutMessage,准备进入下一个循环
                        cur++;
                        break;
                    }
                }
 
                // 调用 DBTCPConnector 的 say 方法执行写入
                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 ) );
 
            // 构造 OutMessage 
            OutMessage query = OutMessage.query( _mongo , options , _fullNameSpace , numToSkip , chooseBatchSize(batchSize, limit, 0) , ref , fields );

            // 调用 DBTCPConnector 的 call 方法获得查询结果
            Response res = _connector.call( _db , this , query , null , 2 );

            // 没有结果
            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;
            }

            // 返回结果            
            return new Result( this , res , batchSize, limit , options );
        }


借助 DBApiLayer.Result 遍历结果


  DBApiLayer.MyCollection._find 方法返回的是 Result 对象,它实现了 Iterator 接口,可以用于遍历。
  next 方法和 hasNext 中都用到了 _advance 方法
        // 获取下一条记录
        public DBObject next(){
            // 当前 cursor 有下一条记录,直接返回
            if ( _cur.hasNext() ) {
                return _cur.next();
            }

            // 没有结果,抛异常
            if ( ! _curResult.hasGetMore( _options ) )
                throw new RuntimeException( "no more" );

           // 有结果,但不在当前 cursor 中,取下一批数据
            _advance();

           // 递归调用
            return next();
        }

        // 是否包含下一条记录
        public boolean hasNext(){
            // 循环检查
            while ( true ){
            // 当前 cursor 有下一条记录,直接返回 true
                if ( _cur.hasNext() )
                    return true;
                
                // 没有结果,返回 false
                if ( ! _curResult.hasGetMore( _options ) )
                    return false;

                // 有结果,但不在当前 cursor 中,取下一批数据
                _advance();
            }
        }

        // 进行到下一条记录
        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 );

            // 输出数据大小
            m.writeInt( chooseBatchSize(_batchSize, _limit, _numFetched) );

            // 输出当前 cusor 的位置
            m.writeLong( _curResult.cursor() );

            // 借助 DBTCPConnector 执行读取操作
            Response res = _connector.call( DBApiLayer.this , _collection , m , _host );

           // 读取下一条 
           _numGetMores++;

            // 初始化
            init( res );
        }
4
3
分享到:
评论

相关推荐

    数据库驱动常见错误"java.lang.ClassNotFoundException:解决了jsp连接Error establishing socket.

    "java.lang.ClassNotFoundException: com.microsoft.jdbc.sqlserver.SQLServerDriver" 解决方案 [Microsoft][SQLServer 2000 Driver for JDBC]Error establishing socket. 解决了jsp连接 sql server 2000的问题

    MongoDB Java Driver 源码分析(1):Package 概述

    本篇文章将聚焦于MongoDB Java Driver的源码分析,首先从Package概述的角度进行深入探讨。 MongoDB Java Driver的源码主要分为以下几个核心包: 1. **com.mongodb**: 这是最顶层的包,包含了驱动的核心组件。`...

    mongodb c#驱动最新驱动mongodb.driver.dll 版本2.12.0-beta1

    标题提到的是 MongoDB 的 C# 驱动的最新版本——mongodb.driver.dll,具体为 2.12.0-beta1 版本。 MongoDB.Driver.dll 是 C# 驱动的核心组件,它包含了连接、查询、更新和操作 MongoDB 数据库所需的所有功能。这个...

    mongodb-java-driver-4.4.0.jar

    mongodb-java-driver-4.4.0.jar

    mongodb-driver-sync-4.2.3-API文档-中英对照版.zip

    标签:mongodb、driver、sync、中英对照文档、jar包、java; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构保持不变,注释和说明精准翻译,...

    mongo-java-driver-3.12.7.jar

    mongo-java-driver-3.12.7 最新版本,java连接MongoDB最新驱动,有需要的可以自行下载

    mongodb-driver-core-4.2.3-API文档-中文版.zip

    标签:mongodb、driver、core、中文文档、jar包、java; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构保持不变,注释和说明精准翻译,请...

    mongodb-driver-sync-4.2.3-API文档-中文版.zip

    标签:mongodb、driver、sync、中文文档、jar包、java; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构保持不变,注释和说明精准翻译,请...

    mongodb-driver-core-3.5.0.jar

    `mongodb-driver-3.5.0.jar`是完整版的MongoDB Java驱动,它扩展了`mongodb-driver-core`,提供了更高级别的操作接口,如`MongoClient`和`MongoDatabase`,方便开发者进行数据库操作。这个驱动程序使开发者能够方便...

    MongoDB Java Driver 简单操作

    ### MongoDB Java Driver 简单操作详解 #### 一、简介 MongoDB 是一款非常流行的文档型数据库系统,因其灵活性和高性能而被广泛应用于多种场景之中。为了方便开发者使用 Java 进行开发,MongoDB 提供了官方的 Java ...

    Java连接mongoDB需要的jar包(3.9.1)

    这里提到的"Java连接mongoDB需要的jar包(3.9.1)"是指Java开发者用于连接MongoDB数据库的一组关键库文件,包括`bson-3.9.1.jar`、`mongodb-driver-3.9.1.jar`和`mongodb-driver-core-3.9.1.jar`。这些JAR文件是...

    mongo-java-driver-3.2.2.jar.zip

    MongoDB是一个流行的开源、文档型数据库系统,而`mongo-java-driver`是官方提供的Java API,允许开发者在Java应用程序中执行各种数据库操作,如读取、写入、查询等。 在本例中,我们讨论的是`mongo-java-driver`的...

    MongoDB_3.8.2驱动jar包及其同版本依赖包bson和mongodb-driver-core

    java和mongodb连接,需要mongodb-driver,您还必须下载其依赖项: bson和 mongodb-driver-core》》3个包: mongodb-driver-3.8.2.jar; bson-3.8.2.jar; mongodb-driver-core-3.8.2.jar

    mongodb-driver-core-4.2.3-API文档-中英对照版.zip

    标签:mongodb、driver、core、中英对照文档、jar包、java; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构保持不变,注释和说明精准翻译,...

    MongoDB c#驱动 dll

    MongoDB.Driver.dll构建在MongoDB.Driver.Core.dll之上,提供了一套更高级别的、易于使用的接口。 在C#中使用这些DLL,开发者首先需要安装MongoDB.CSharpDriver NuGet包,这将自动引入所有必需的依赖。然后,可以...

    【解决方案】pyspark 初次连接mongo 时报错Class not found exception:com.mongodb.spark.sql.DefaultSource

     df = spark.read.format(com.mongodb.spark.sql.DefaultSource).load()  File /home/cisco/spark-2.2.0-bin-hadoop2.7/python/lib/pyspark.zip/pyspark/sql/readwriter.py, line 165, in load  

    mongodb-java-driver-3.5.0.jar最新驱动包

    亲测可用,解压包含三个jar包,引用时sources和doc包根据需要添加。 mongo-java-driver-3.5.0.jar; mongo-java-driver-3.5.0-javadoc.jar; mongo-java-driver-3.5.0-sources.jar;

    mongodb-async-driver-2.0.1 jar包

    MongoDB异步驱动程序(mongodb-async-driver)是为Java开发者设计的一个库,它允许应用程序以非阻塞的方式与MongoDB服务器进行通信,提高了处理大量并发请求的能力。 在"mongodb-async-driver-2.0.1.jar"这个特定...

    mongoDB java driver api

    MongoDB Java驱动API是用于与MongoDB数据库交互的Java库,它是MongoDB官方提供的一个关键组件,使得Java开发者能够方便地在应用程序中存取数据。MongoDB是一个高性能、开源、无模式的文档型数据库,而Java驱动API则...

    mongodb-java-driver源码依赖库

    10. **`com.mongodb.async.*`**:对于异步编程,MongoDB Java Driver提供了异步版本的客户端和集合操作,以配合Java 8的 CompletableFuture 或其他异步库。 了解这些核心概念后,开发者可以更有效地使用MongoDB ...

Global site tag (gtag.js) - Google Analytics