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

MongoDB Java Driver 源码分析(5):com.mongodb.DB

阅读更多
DB 表示数据库连接,是一个抽象类,部分核心功能由子类提供,由 DBApiLayer 继承。

由子类实现的抽象方法

// 开始数据库连接
public abstract void requestStart();
// 结束数据库连接
public abstract void requestDone();
// 保持数据库连接
public abstract void requestEnsureConnection();

// 获取指定名称的数据集
protected abstract DBCollection doGetCollection( String name );


数据集相关的方法

    // 创建数据集
    public final DBCollection createCollection( String name, DBObject options ){
        // 如果 options 不为空
        // 则先以 options 构造创建数据库的命令
        // 然后执行创建数据库的命令并得到结果
        if ( options != null ){
            DBObject createCmd = new BasicDBObject("create", name);
            createCmd.putAll(options);
            CommandResult result = command(createCmd);
            result.throwOnError();
        }

        return getCollection(name);
    }

    // 解析用 "." 分隔的字符串,获取指定的数据集
    public DBCollection getCollectionFromString( String s ){
        DBCollection foo = null;

        // 获取 "." 所在位置
        int idx = s.indexOf( "." );

        // 当分解后的字符串中仍然包含 "." 时
        // 循环分解字符串,知道所有 "." 号解析完毕
        // 效果类似于递归调用,但这里采用了循环的写法
        while ( idx >= 0 ){
            // 获取 "." 之前的字符串 b
            String b = s.substring( 0 , idx );
            // 获取 "." 之后的字符串 s
            s = s.substring( idx + 1 );

            // 检查上次解析得到的对象 foo 是否为空
            if ( foo == null )
                foo = getCollection( b );
            else
                foo = foo.getCollection( b );

            // 获取 "." 所在位置
            idx = s.indexOf( "." );
        }

        if ( foo != null )
            return foo.getCollection( s );

        return getCollection( s );
    }

    // 获取所有数据集名称
    public Set<String> getCollectionNames()
        throws MongoException {

        // 获取系统的 namespace 数据集
        DBCollection namespaces = getCollection("system.namespaces");
        if (namespaces == null)
            throw new RuntimeException("this is impossible");

        // 获取用于遍历 namespace 的迭代器
        Iterator<DBObject> i = namespaces.__find(new BasicDBObject(), null, 0, 0, 0, getOptions());
        if (i == null)
            return new HashSet<String>();

        // 表名称 List,最后转换为 set 并返回
        List<String> tables = new ArrayList<String>();

        for (; i.hasNext();) {
            DBObject o = i.next();
            if ( o.get( "name" ) == null ){
                throw new MongoException( "how is name null : " + o );
            }

            // 获取 namespace 名称
            String n = o.get("name").toString();

            // 获取 namespace 名称前缀
            int idx = n.indexOf(".");
            String root = n.substring(0, idx);

            // 如果前缀不为当前 DB 的名称
            // 表示这个 namespace 不属于当前 DB
            if (!root.equals(_name))
                continue;

            // 忽略特殊数据集
            if (n.indexOf("$") >= 0)
                continue;

            // 获取数据集名称
            String table = n.substring(idx + 1);

            tables.add(table);
        }

        Collections.sort(tables);

        // 转换为 Set
        return new LinkedHashSet<String>(tables);
    }


数据库命令相关的方法

    // 执行数据库命令
    public CommandResult command( DBObject cmd , int options )
        throws MongoException {

        // 调用 DBCollection 的 find 方法        
        Iterator<DBObject> i = getCollection("$cmd").__find(cmd, new BasicDBObject(), 0, -1, 0, options);
        if ( i == null || ! i.hasNext() )
            return null;
 
        // 获得数据库命令的返回结果结果       
        CommandResult res = (CommandResult)i.next();
        res._cmd = cmd;
        return res;
    }

    // 以 "eval" 方式解析命令
    public CommandResult doEval( String code , Object ... args )
        throws MongoException {

        // 构造 "eval" 命令
        // 调用 command 方法执行并获得结果
        return command( BasicDBObjectBuilder.start()
                        .add( "$eval" , code )
                        .add( "args" , args )
                        .get() );
    }

    // 删除数据库
    public void dropDatabase()
        throws MongoException {

        CommandResult res = command(new BasicDBObject("dropDatabase", 1));
        res.throwOnError();
        _mongo._dbs.remove(this.getName());
    }


用户相关的方法

    // 验证用户名和密码
    public CommandResult authenticateCommand(String username, char[] passwd )
        throws MongoException {

        if ( username == null || passwd == null )
            throw new NullPointerException( "username can't be null" );

        if ( _username != null )
	    throw new IllegalStateException( "can't call authenticate twice on the same DBObject" );

        // 根据用户名和密码,通过 MD5 计算哈希值 
        String hash = _hash( username , passwd );

        // 验证用户名和密码并获得返回结果
        CommandResult res = _doauth( username , hash.getBytes() );
        res.throwOnError();
        _username = username;
        _authhash = hash.getBytes();
        return res;
    }

    // 验证用户名和密码并获得返回结果
    private CommandResult _doauth( String username , byte[] hash ){
        // 获取 "盐值",用于加密
        CommandResult res = command(new BasicDBObject("getnonce", 1), getOptions());
        res.throwOnError();

        // 利用当前的用户名和密码,执行一个没有实际意义的操作
        // 利用 username, 加密后的密码,以及盐值进行验证,看看是否产生错误
        DBObject cmd = _authCommand( res.getString( "nonce" ) , username , hash );
        return command(cmd, getOptions());
    }


    // 利用 username, 加密后的密码,以及盐值进行验证,看看是否产生错误
    static DBObject _authCommand( String nonce , String username , byte[] hash ){
        // 获取由 username, 加密后的密码,以及盐值 组成的 key
        String key = nonce + username + new String( hash );

        // 构造用于验证用户的命令
        BasicDBObject cmd = new BasicDBObject();

        cmd.put("authenticate", 1);
        cmd.put("user", username);
        cmd.put("nonce", nonce);

        // 对 key 进行 MD5 加密
        cmd.put("key", Util.hexMD5(key.getBytes()));
        
        return cmd;
    }

    // 添加用户
    public WriteResult addUser( String username , char[] passwd, boolean readOnly ){
        // 获取系统用户
        DBCollection c = getCollection( "system.users" );

        // 根据指定的 username 获取用户
        DBObject o = c.findOne( new BasicDBObject( "user" , username ) );
        // 如果不存在,则创建
        if ( o == null )
            o = new BasicDBObject( "user" , username );

        // 设置密码
        o.put( "pwd" , _hash( username , passwd ) );
        // 设置只读权限
        o.put( "readOnly" , readOnly );

        // 将构造出来的用户对象添加到 系统用户数据集 中
        return c.save( o );
    }

    // 删除用户
    public WriteResult removeUser( String username ){
        DBCollection c = getCollection( "system.users" );
        return c.remove(new BasicDBObject( "user" , username ));
    }
3
2
分享到:
评论

相关推荐

    MongoDB Java Driver 简单操作

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

    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;

    Pure JS (4.3): pure.db.js 的实现(基于 MongoDB Rhino Driver)

    《纯JavaScript实现:pure.db.js基于MongoDB Rhino Driver详解》 在JavaScript的世界里,数据库操作通常依赖于服务器端的语言支持,如PHP、Python或Node.js等。然而,有一种另辟蹊径的方式,即通过Rhino JavaScript...

    MongoDBjava各版本驱动下载

    MongoDB Java驱动是Java开发者与MongoDB数据库交互的重要工具,它允许Java应用程序通过标准的Java API来执行查询、插入、更新和删除等操作。在Java中使用MongoDB,首先需要安装并配置对应的驱动版本,以确保与正在...

    Mongodb java包

    1. **mongodb-driver-3.6.0.jar**:这是MongoDB Java驱动程序的主要组件,它包含了连接MongoDB服务器、执行查询、更新和插入操作等所需的所有类和接口。3.6.0版本是这个驱动的一个特定版本,确保了与MongoDB 3.6版本...

    mongodb.dll 下载.zip

    例如,`db.collection.insertOne()`用于插入单个文档,`db.collection.find()`用于查询数据。 4. **聚合框架**:MongoDB提供了强大的聚合框架,允许用户进行复杂的数据处理和分析,类似SQL的GROUP BY和JOIN操作。 ...

    MongoDB Java连接数据库.pdf

    驱动程序可以从 GitHub 的官方仓库(如:github.com/mongodb/mongo-java-driver/downloads)获取。请确保下载最新版本,以利用最新的特性和性能优化。下载完成后,将 `mongo.jar` 文件添加到你的项目类路径 ...

    java操作mongodb增删改查

    ### Java操作MongoDB进行增删改查详解 #### 一、引言 在现代软件开发中,非关系型数据库如MongoDB因其灵活性和扩展性而备受青睐。Java作为一种广泛使用的编程语言,在操作MongoDB时提供了丰富的API支持。本文将详细...

    mongo-java-driver-3.4.2.jar

    mongo-java-driver-3.4.2.jar

    MongoDB Java API 中文

    ### MongoDB Java API 使用详解 #### 一、Java 驱动简介与一致性 MongoDB 的 Java 驱动是线程安全的,适用于大多数应用程序场景。通常情况下,只需要创建一个 `Mongo` 实例即可,因为它内部包含了一个连接池(默认...

    java 执行cmd命令及mongodb脚本

    Java执行CMD命令及MongoDB脚本是开发过程中常见的任务,特别是在集成系统或者自动化运维场景下。下面将详细讲解这两个主题。 一、Java执行CMD命令 在Java中,我们可以使用Runtime类或ProcessBuilder类来执行操作...

    mongodb安装及java操作demo收集.pdf

    - 访问 Maven 仓库下载 MongoDB 驱动: [http://central.maven.org/maven2/org/mongodb/mongo-java-driver](http://central.maven.org/maven2/org/mongodb/mongo-java-driver) - 示例中使用的驱动版本为 2.5,但...

    MongoDB Java获取集合.pdf

    Java 是广泛使用的编程语言,MongoDB 提供了 Java 驱动程序,使得开发者可以轻松地在 Java 应用程序中操作 MongoDB 数据库。在本文中,我们将详细探讨如何使用 Java MongoDB 驱动程序来获取集合。 首先,我们需要...

    java 操作mongodb 增删改查

    在Java编程环境中,MongoDB是一个广泛使用的文档型数据库,它以JSON格式存储数据,提供了高性能、高可用性和可扩展性。本教程将详细介绍如何使用Java进行MongoDB的基本操作,包括增(添加数据)、删(删除数据)、改...

    mongodb 3.4.2 java包

    10. **监控和诊断**:MongoDB提供了丰富的诊断工具,如`db.serverStatus()`和`db.stats()`,在Java应用中,开发者可以通过执行这些命令获取关于MongoDB实例的运行状态和统计信息,用于故障排查和性能调优。...

    mongodb java 简单操作 win32 安装步骤

    MongoDB是一款开源、分布式、高性能的文档型数据库,广泛应用于Web开发、数据分析、存储大量非结构化数据等场景。在Windows 32位系统上安装MongoDB并进行Java操作涉及以下关键步骤: **一、MongoDB的Win32安装** 1...

    java 操作mongodb

    - 下载 MongoDB 的 Java 驱动包,可以从官方 GitHub 页面下载:https://github.com/mongodb/mongo-java-driver/downloads - 在 Java 项目中导入下载的驱动包,例如在 Eclipse 或 MyEclipse 中,将 jar 包添加到...

    jdbc java mongodb mysql 相互同步

    5. **手动编程**:直接编写Java代码,通过JDBC和MongoDB Java Driver读写数据,实现定制化的同步逻辑。 在实际应用中,应根据项目需求选择合适的数据同步策略。例如,如果对实时性要求不高,可以选择定时任务;如果...

    MongoDB 在java中的应用 纯Java操作

    ### MongoDB在Java中的应用 #### 一、MongoDB简介与安装步骤 MongoDB是一种非常流行的NoSQL数据库系统,尤其适用于需要处理非结构化或半结构化数据的应用场景。其灵活性和扩展性使得它成为众多开发者的首选。在...

Global site tag (gtag.js) - Google Analytics