千家信息网

java连接mongodb源码解读

发表于:2026-10-31 作者:千家信息网编辑
千家信息网最后更新 2026年10月31日,用mongdb也大半年了,一直是业务上的逻辑实现了就ok。然而这样并不能进步……因此今天查了查java连接mongodb驱动的源码,搜到的各种信息整合一下,方便以后深入的使用。先贴连接数据库代码 Li
千家信息网最后更新 2026年10月31日java连接mongodb源码解读

用mongdb也大半年了,一直是业务上的逻辑实现了就ok。然而这样并不能进步……因此今天查了查java连接mongodb驱动的源码,搜到的各种信息整合一下,方便以后深入的使用。

先贴连接数据库代码

 List replicaSet = new         ArrayList();         replicaSet.add(new ServerAddress("127.0.0.1", 27017));         MongoClientOptions option =         MongoClientOptions.builder().autoConnectRetry(true).connectionsPerHost(300).maxWaitTime(30000).build();         MongoConnection.init(replicaSet, option, "test"); public static synchronized void init(List replicaSet,                        MongoClientOptions option, String defaultDb){                mongo = new MongoClient(replicaSet, option);                mongo.setReadPreference(ReadPreference.nearest());                setDb(mongo.getDB(defaultDb));        }

当初一眼看过去也是头大无比,就跟大学背下来的连接mysql数据库驱动一样,只求考试默写下来不挂科。虽然也能用,但是不求甚解的态度明显是错误的!接下来分解下来一步一步看吧:

    public ServerAddress( String host , int port )        throws UnknownHostException {        if ( host == null )            host = defaultHost();        host = host.trim();        if ( host.length() == 0 )            host = defaultHost();                int idx = host.indexOf( ":" );        if ( idx > 0 ){            if ( port != defaultPort() )                throw new IllegalArgumentException( "can't specify port in construct and via host" );            port = Integer.parseInt( host.substring( idx + 1 ) );            host = host.substring( 0 , idx ).trim();        }        _host = host;        _port = port;        updateInetAddress();    }

replicaSet显然是一个服务器地址数组,点进去后是对IP地址以及端口的解析。如果填写的地址是127.0.0.1:27017样式的话,冒号之后的端口必须是27017,否则就抛出异常告诉你不能自己构建主机及端口。不过既然使用了带host以及port的构造方法,地址和端口分开写就好了,何必放在一块……

boolean updateInetAddress() throws UnknownHostException {        InetSocketAddress oldAddress = _address;        _address = new InetSocketAddress( InetAddress.getByName(_host) , _port );        return !_address.equals(oldAddress);    }    volatile InetSocketAddress _address;

至于updateInetAddress(),InetAddress是java对ip地址的封装,方便其他网络类调用,方法内部对ipv4和ipv6有各种详细的判定,不多赘述,毕竟是基础类,有时间认真学习一下提升会非常大。详细内容在这个博客里面http://my.oschina.net/fhd/blog/371997有提及。volatile是一个类型修饰符(type specifier)。它是被设计用来修饰被不同线程访问和修改的变量。如果不加入volatile,要么无法编写多线程程序,要么编译器失去大量优化的机会。回到第一块,MongoClientOptions是对数据库的一些设置,用到了人民喜闻乐见的构建者模式builder:

        private String description;        private int connectionsPerHost = 100;        private int threadsAllowedToBlockForConnectionMultiplier = 5;        private int maxWaitTime = 1000 * 60 * 2;        private int connectTimeout = 1000 * 10;        private int socketTimeout = 0;        private boolean socketKeepAlive = false;        private boolean autoConnectRetry = false;        private long maxAutoConnectRetryTime = 0;        private ReadPreference readPreference = ReadPreference.primary();        private DBDecoderFactory dbDecoderFactory = DefaultDBDecoder.FACTORY;        private DBEncoderFactory dbEncoderFactory = DefaultDBEncoder.FACTORY;        private WriteConcern writeConcern = WriteConcern.ACKNOWLEDGED;        private SocketFactory socketFactory = SocketFactory.getDefault();        private boolean cursorFinalizerEnabled = true;        private boolean alwaysUseMBeans = false;

builder给需要初始化的成员变量赋值。一个一个看吧~

  • connectionsPerHost:每个主机的连接数

  • threadsAllowedToBlockForConnectionMultiplier:线程队列数,它以上面 connectionsPerHost值相乘的结果就是线程队列最大值。如果连接线程排满了队列就会抛出"Out of semaphores to get db"错误。

  • maxWaitTime:最大等待连接的线程阻塞时间

  • connectTimeout:连接超时的毫秒。0是默认和无限

  • socketTimeout:socket超时。0是默认和无限

  • autoConnectRetry:这个控制是否在一个连接时,系统会自动重试

以上解释似乎在各种需要线程池的数据库连接驱动都通用……ReadPrefrence是多个节点时读操作的设置,默认是只从主节点进行读操作,还有其他属性如只从第二节点读、从主节点读,若不可读取则再去从节点读取等等。目前还没有用到过……之前的代码设置的是从离最近的节点读取mongo.setReadPreference(ReadPreference.nearest())。然而我们的程序只有一个节点……并没有什么卵用。WriteConcern用来保障写操作的可靠性,是性能和可靠性之间的一个平衡,http://kyfxbl.iteye.com/blog/1952941这个博客中讲的比较详细。简单来说就是保障写操作确实入库了,不会因为网络状况或者服务器挂掉导致写入失败的时候得不到提醒,如果这个参数设置w:-1则得不到任何异常信息,默认w:1,最好也设置jurnal:true,写操作写入内存的同时也写入journal文件,这样如果mongod非正常down掉,重启以后就可以根据journal文件中的内容,来还原写操作。更高级别则是对多个节点的集群进行设置了,只有一个节点的话w:1&journal:true就够用了。所以第一块代码中的init方法里的synchronized到底需不需要呢……mongo既然本身就是一个线程安全的实例,mongoclient继承了mongo,是不是也意味着不需要在初始化mongoclient时进行同步。


节点 线程 地址 数据 数据库 端口 代码 就是 方法 队列 驱动 最大 主机 信息 内容 博客 变量 只有 可靠性 多个 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 互联网科技海报 广东万易互联网科技有限公司惠州分公司 深圳科技互联网 合肥互联网科技公司 互联网科技上市公司 有木互联网科技 广州善班互联网科技 团飞科技与伯堂互联网服务平台 汽车互联网创新科技园 互联网大会黑科技排名 彤创互联网科技有限公司 广州市恰铎互联网科技有限公司 科技类公司包括互联网吗 工业互联网等科技实现智能化赋能 厦门江牛科技互联网 有人说阿里系是互联网科技企业 九思连强互联网电子科技有限公司 数字互联网科技有限公司 前海云享互联网科技 科技发展第三阶段互联网时代 互联网 科技 互联网的科技创新 天津摩尔互联网科技 互联网科技博主是什么意思 互联网5g黑科技有哪些 互联网科技大奖都有哪些公司 电子科技大学互联网创业大赛 上海万顺科技互联网有限公司招聘 科技互联网专业务虚会材料 互联网企业和网络科技有限公司
0