• Java程序中与MongoDB建立连接~小记


    1.Mongo和MongoClient的关系

    MongoClient继承自Mongo,使用Mongo也可建立连接,但是需要使用与Mongo适应的MongoOptions,MongoURI等类型。

    2.建立连接

    在MongoDB Java Driver API中,要操作MongoDB的第一步和使用其他DB Java Driver类似,都需要首先和数据库建立连接。在MongoDBJava Driver API中,建立连接的类为com.mongodb.MongoClient.在讨论连接字符串等内容之前,我们来看看它最简单的使用方式:

    MongoClient client = new MongoClient();

    一个构造函数不带任何参数的版本。使用这个构造函数连接到的是本地的MongoDB服务,即/127.0.0.1:27017,当然你如果改变了MongoDB服务的端口,那么这里显示的端口就是你的端口了。

    可以通过以下单元测试代码进行验证:

    @Test  
    public void testConstruactors() throws UnknownHostException {  
        MongoClient client;       
        client = new MongoClient();  
        //也可指定连接的Host:
        //client = new MongoClient("127.0.0.1");  
        assertEquals(new ServerAddress(), client.getAddress());  
        client.close();  
    }  
    3.设置连接的各项属性
    和其他DB Java Driver的连接一样,MongoDB Java Driver的连接也提供了很多属性,来一起了解其中几个。要设置MongoClient有关连接的属性,需要用到com.mongodb.MongoClientOpations类。这个类包含了 MongoClient建立连接时,与连接相关的所有属性。该类提供了一Builder模式的方式创建并设置这些属性的值。
    MongoClientOptions customClientOptions = new MongoClientOptions.Builder().connectionsPerHost(100).build();

    分析上面的代码,MongoClientOptions.Builder()得到的是一个MongoClientOptions的Builder,通过该Builder可以设置各种Options,例如connectionsPerHost(100),设置连接池中最大连接个数,需要注意的是,每个属性的设置方法的返回类型是一个Builder,这意味着可以采用类似下面的链式调用

    MongoClientOptions customClientOptions = new MongoClientOptions.Builder().connectionsPerHost(100).threadsAllowedToBlockForConnectionMultiplier(200).build(); 
    最后,当我们将需要的各项值设定好后,就调用Builder的builder()方法,得到一个MongoClientOptions对象。问题来了,上面的代码只是为各项连接相关的属性赋值,那如何将这些值交给MongoClient,让它按照给出的属性值来建立连接呢?
     
    答案就是MongoClient的构造函数,如下所示:
    MongoClientOptions customClientOptions = new MongoClientOptions.Builder().connectionsPerHost(50).maxWaitTime(2000).build();  
    MongoOptions options = new MongoOptions(customClientOptions);  
    client = new MongoClient("127.0.0.1", customClientOptions);  // 每个MongoClient实例维护一个连接池
    assertEquals(new ServerAddress("127.0.0.1"), client.getAddress());  
    assertEquals(options, client.getMongoOptions());  
    client.close();  

    MongoOptions options=new MongoOptions(customClientOptions):这行代码并不影响MongoClientOptions的使用,只是展示如何获取到设置的MongoClientOptions。

    此外,也可直接通过MongoClient.getMongoOptions()获取到MongoOptions后,进行设置,而不使用MongoClientOptions,如下

    MongoOptions mps = mongoClient.getMongoOptions();  
    mps.setConnectionsPerHost(mongoDBConfig.getPoolSize());  
    mps.setConnectTimeout(mongoDBConfig.getConnectTimeout());  
    mps.setMaxWaitTime(mongoDBConfig.getMaxWaitTime());  

    通过两种方式的对比,我更喜欢MongoClientOptions,代码更加优雅。另外,即使没有设置MongoClientOptions,MongoClient也会有默认的设置。

    4.使用连接字符串进行连接
    上面的连接只是指定了连接到MongoDB的服务,但是具体连接到哪个数据库呢?使用什么样的登录名和密码呢?这个时候就用到连接字符串了,我们先解释下MongoDB的连接字符串,如下:
    mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]]

    最简单的连接字符串就是:mongodb://127.0.0.1

    当然,在真正在项目开发中,没人会这么用!!!!!!~~~回到主题,在MongoClient中,如何使用连接字符串进行连接呢?MongoDB Java Driver提供了一个 com.mongodb.MongoClientURI类型,使用方式如下:

    client = new MongoClient(new MongoClientURI("mongodb://kwiner:test123@127.0.0.1/test?authMechanism=MONGODB-CR&maxPoolSize=500"));  
    client.close();  

    5.安全连接方式

    MongoClient也提供了用户名和密码连接到指定数据库的方式,需要用到com.mongodb.MongoCredential,该类在mongo-java-driver的2.11.0版本中才开始提供,请注意!

    MongoClientOptions clientOptions=new MongoClientOptions.Builder().connectionsPerHost(poolSize).threadsAllowedToBlockForConnectionMultiplier(200).build();
    List<MongoCredential> lstCredentials = Arrays.asList(MongoCredential.createMongoCRCredential("admin", "myinfo", "123456".toCharArray()));  
    client = new MongoClient(new ServerAddress("127.0.0.1"),lstCredentials, clientOptions);  
    client.close();  
    
    或者
    
    MongoClientOptions mongoOptions=new MongoClientOptions.Builder().connectionsPerHost(poolSize).threadsAllowedToBlockForConnectionMultiplier(200).build();
    MongoClient mongoClient = new MongoClient(new ServerAddress(server, port), mongoOptions); // 每个MongoClient实例维护一个连接池
    try {
    db = mongoClient.getDatabase(database); collection = db.getCollection(table); catch (Exception e) {   mongoClient.close();   throw e; }
    6.连接池
    MongoClient本身就使用了连接池,如果我们使用了MongoClientOptions,则默认是100个连接
    MongoClientOptions.Builder builder = new MongoClientOptions.Builder();  
    MongoClientOptions options = builder.build();  
    assertEquals(100, options.getConnectionsPerHost());//最大连接数  
    assertEquals(0, options.getMinConnectionsPerHost());//最小连接数  
    assertEquals(0, options.getMaxConnectionIdleTime());//连接的最大闲置时间  
    assertEquals(0, options.getMaxConnectionLifeTime());//连接的最大生存时间  
    assertEquals(120000, options.getMaxWaitTime());//最大等待可用连接的时间  
    assertEquals(10000, options.getConnectTimeout());//连接超时时间  
      
    MongoClient client = new MongoClient("127.0.0.1", customClientOptions);  
    client.close();  
    其中, 闲置时间和生存时间为0,表示无限制。
    MongoClient的close方法会关闭底层连接,MongoClient的实例将变得不可用,应该根据程序的需要,适当的调用该方法,释放资源。

    7.连接副本集

    使用MongoDB作为数据库,基本上都会使用副本集,在这个集里面,有primary节点,又有其他secondary节点,并使用了读写分离,这个时候,使用java连接MongoDB服务应该怎么做呢? 其实很简单,就是使用一个ServerAddress集合保存副本集中的所有节点,然后作为MongoClient的构造函数的参数,并使用ReadPreference设置读写策略,注意,ReadPreference的读写策略既可以在MongoClient上设置,作用与使用MongoClient连接的所有操作,也可以设置到每次具体的集合操作上,作用域该次操作。代码如下:

    在MongoClient上设置读写策略:

    List<ServerAddress> addresses = new ArrayList<ServerAddress>();  
    ServerAddress address1 = new ServerAddress("192.168.1.136" , 27017);  
    ServerAddress address2 = new ServerAddress("192.168.1.137" , 27017);  
    ServerAddress address3 = new ServerAddress("192.168.1.138" , 27017);  
    addresses.add(address1);  
    addresses.add(address2);  
    addresses.add(address3);  
      
    mongoClient = new MongoClient(lstAddrs);  
    mongoClient.setReadPreference(ReadPreference.primary()); 

    在某次操作上设置读写策略:

    List<ServerAddress> addresses = new ArrayList<ServerAddress>();  
    ServerAddress address1 = new ServerAddress("192.168.1.136" , 27017);  
    ServerAddress address2 = new ServerAddress("192.168.1.137" , 27017);  
    ServerAddress address3 = new ServerAddress("192.168.1.138" , 27017);  
    addresses.add(address1);  
    addresses.add(address2);  
    addresses.add(address3);  
       
    MongoClient client = new MongoClient(addresses);  
    DB db = client.getDB( "test" );  
    DBCollection coll = db.getCollection( "test" );  
       
    BasicDBObject object = new BasicDBObject();  
    object.append( "test2" , "testval2" );  
       
    //读操作从副本节点读取  
    ReadPreference preference = ReadPreference.secondary();  
    DBObject dbObject = coll.findOne(object, null , preference);  
    System.out.println(dbObject);  

    8.mongo连接池属性设置

    Mongo的实例其实就是一个数据库连接池,这个连接池里默认有10个链接。我们没有必要重新实现这个链接池,但是我们可以更改这个连接池的配置。因为Mongo的实例就是一个连接池,所以,项目中最好只存在一个Mongo的实例。

    常见的配置参数:

    connectionsPerHost:每个主机的连接数

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

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

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

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

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

    还有许多配置,可以参见mongodb的API。

  • 相关阅读:
    Yii2 分页
    Yii2 或者当前登录用户帐号
    css3媒体查询判断移动设备横竖屏
    Javascript操作Tr隐藏显示变形~
    php注释标准
    匹配一段html中所有的src
    数据库遇到错误(随时补充)
    NetCore-缓存文件上传和文件流上传
    SVN跨服务器版本迁移
    发票同步微信卡包
  • 原文地址:https://www.cnblogs.com/AngelaSunny/p/6362970.html
Copyright © 2020-2023  润新知