最近花了一些时间学习了下MongoDB数据库,感觉还是比较全面系统的,涉及了软件安装、客户端操作、安全认证、副本集和分布式集群搭建,以及使用Spring Data连接MongoDB进行数据操作,收获很大。特此记录,以备查看。
文章目录:
MongoDB和Java(1):Linux下的MongoDB安装
MongoDB和Java(2):普通用户启动mongod进程
MongoDB和Java(4):Spring Data整合MongoDB(XML配置)
MongoDB和Java(5):Spring Data整合MongoDB(注解配置)
MongoDB和Java(6):Spring Data整合MongoDB副本集、分片集群
本文记录如何使用mongodb-driver连接mongodb数据库,以及进行简单的增删改查操作,使用起来还是比较简单的。
源代码下载
MongoDB和Java学习代码.zip
1、环境和依赖
MongoDB服务器操作系统 CentOS 6.5
MongoDB版本 4.0.2
客户端操作系统 Windows 7 64位
Eclipse Luna Service Release 2 (4.4.2)
Maven 3.2.1
JDK 1.8.0_141
我们使用mongodb-driver 3.6.4编写代码
首先引入依赖
1 <dependency> 2 <groupId>junit</groupId> 3 <artifactId>junit</artifactId> 4 <version>4.10</version> 5 <scope>test</scope> 6 </dependency> 7 <dependency> 8 <groupId>org.mongodb</groupId> 9 <artifactId>mongodb-driver</artifactId> 10 <version>3.6.4</version> 11 </dependency> 12 <dependency> 13 <groupId>ch.qos.logback</groupId> 14 <artifactId>logback-core</artifactId> 15 <version>1.1.7</version> 16 </dependency> 17 <dependency> 18 <groupId>ch.qos.logback</groupId> 19 <artifactId>logback-classic</artifactId> 20 <version>1.1.7</version> 21 </dependency>
2、连接MongoDB服务器
1 MongoClient mongoClient = null; 2 3 try { 4 5 mongoClient = new MongoClient("10.10.12.195", 27017); 6 7 // show dbs 8 MongoIterable<String> databaseNames = mongoClient.listDatabaseNames(); 9 for (String name : databaseNames) { 10 System.out.println(name); 11 } 12 13 // 连接test库 14 MongoDatabase mgdb = mongoClient.getDatabase("test"); 15 System.out.println("MongoDatabase inof is: " + mgdb.getName()); 16 17 // show collections 18 MongoIterable<String> names = mgdb.listCollectionNames(); 19 for (String name : names) { 20 System.out.println(name); 21 } 22 } catch (Exception e) { 23 } finally { 24 mongoClient.close(); 25 }
MongoClient是具有内部连接池的MongoDB客户端。对于大多数应用程序,整个JVM有一个MongoClient对象就可以了。
在示例代码中使用了传入IP、端口的构造方法创建了MongoClient对象。
以下是等效的,都连接到默认端口上运行的本地数据库:
1 MongoClient mongoClient1 = new MongoClient(); 2 MongoClient mongoClient1 = new MongoClient("localhost"); 3 MongoClient mongoClient2 = new MongoClient("localhost", 27017); 4 MongoClient mongoClient4 = new MongoClient(new ServerAddress("localhost")); 5 MongoClient mongoClient5 = new MongoClient(new ServerAddress("localhost"), MongoClientOptions.builder().build());
也可以通过将ServerAddress列表传递给MongoClient构造函数来连接副本集。例如:
1 MongoClient mongoClient = new MongoClient(Arrays.asList( 2 new ServerAddress("localhost", 27017), 3 new ServerAddress("localhost", 27018), 4 new ServerAddress("localhost", 27019)));
还可以使用相同的构造方法连接到分片群集。MongoClient将自动检测服务器是否是副本集成员列表或mongos服务器列表。
示例代码中使用了获取全部数据库名称列表和切换数据库的方法
a. 可以使用getDatabase("test")方法获取指定数据库,此方法返回一个MongoDatabase对象即当前数据库
b. 可以使用listDatabaseNames()获取全部数据库
1 // show dbs 2 MongoIterable<String> databaseNames = mongoClient.listDatabaseNames(); 3 for (String name : databaseNames) { 4 System.out.println(name); 5 }
3、创建和列出集合
1 MongoClient mongoClient = null; 2 3 try { 4 5 mongoClient = new MongoClient("10.10.12.195", 27017); 6 7 // 连接test库 8 MongoDatabase mgdb = mongoClient.getDatabase("test"); 9 10 // 创建employee集合 11 mgdb.createCollection("employee"); 12 System.out.println("Create collection: employee"); 13 14 // show collections 15 MongoIterable<String> names = mgdb.listCollectionNames(); 16 for (String name : names) { 17 System.out.println(name); 18 } 19 20 } catch (Exception e) { 21 } finally { 22 mongoClient.close(); 23 }
MongoDatabase类的createCollection("name")可以创建指定名称的集合
MongoDatabase还有一些其他方法,此处列出主要的:
1 MongoCollection<Document> getCollection(String collectionName); 2 MongoIterable<String> listCollectionNames(); 3 ListCollectionsIterable<Document> listCollections(); 4 void createCollection(String collectionName); 5 void createCollection(String collectionName, CreateCollectionOptions createCollectionOptions);
4、文档的插入、查询和删除
1 MongoClient mongoClient = null; 2 3 try { 4 5 mongoClient = new MongoClient("10.10.12.195", 27017); 6 7 // 连接test库 8 MongoDatabase mgdb = mongoClient.getDatabase("test"); 9 10 // 获取集合 11 MongoCollection<Document> emps = mgdb.getCollection("employee"); 12 13 // 创建文档 14 Document document = new Document().append("name", "administrator").append("age", 20); 15 16 // 插入文档 17 emps.insertOne(document); 18 19 // 查询数据量 20 long rows = emps.count(); 21 System.out.println(rows); 22 // 查询全部数据 23 FindIterable<Document> find = emps.find(); 24 for (Document d : find) { 25 Set<String> set = d.keySet(); 26 for (String k : set) { 27 System.out.println(k + ": " + d.get(k)); 28 } 29 } 30 31 // 删除数据 32 emps.deleteMany(new BsonDocument()); 33 34 } catch (Exception e) { 35 } finally { 36 mongoClient.close(); 37 }
MongoDatabase的getCollection("employee")方法可以获取指定名称的集合即MongoCollection<Document>对象
调用insertOne方法即可向集合中插入一个文档Document对象
看下文档的创建,链式语法,可以使用append方法向文档中添加字段和值
Document document = new Document().append("name", "administrator").append("age", 20);
MongoCollection的find()方法可以查询集合全部数据
1 // 查询全部数据 2 FindIterable<Document> find = emps.find(); 3 for (Document d : find) { 4 Set<String> set = d.keySet(); 5 for (String k : set) { 6 System.out.println(k + ": " + d.get(k)); 7 } 8 }
有一个重载的 find(Bson filter) 可以查询指定条件的数据,在更新示例中会介绍Bson 的使用方法
删除数据
emps.deleteMany(new BsonDocument());
类似find方法,删除数据时也可以传入一个Bson对象指定过滤条件
5、文档更新、Bson和Filters工具类
1 // 获取集合 2 MongoCollection<Document> emps = mgdb.getCollection("employee"); 3 4 // 创建文档 5 Document document = new Document().append("name", "administrator").append("age", 20); 6 7 // 插入文档 8 emps.insertOne(document); 9 10 // 更新数据 11 emps.updateOne(Filters.eq("name", "administrator"), new Document("$set", new Document("name", "administrator2")));
我们此处使用了updateOne方法更新了一条数据,该方法接收两个参数:第一个参数是Bson对象设置查询条件;第二个参数是一个文档对象指定如何更新数据。
Bson接口通常用于条件过滤,我们可以使用Filters工具类来快速的构建条件。
Filters工具类是一个用于构建查询过滤器的工厂。使用此类的一种便捷方法是静态导入其所有方法,允许使用如下:
collection.find(and(eq("x", 1), lt("y", 3)));
有很多静态方法可以使用:
6、连接池特性
Mongo实例就是一个数据库连接池,默认有10个链接。没有必要重新实现这个连接池,但是可以更改配置。所以,项目中最好只存在一个Mongo的实例。
MongoClientOptions.Builder.connectionsPerHost(int)设置每个主机的最大连接数
MongoClientOptions.Builder.threadsAllowedToBlockForConnectionMultiplier(int)设置线程队列数,与上面connectionsPerHost值相乘的结果就是线程队列最大值。如果连接线程排满了队列就会抛出“Out of semaphores to get db”错误
MongoClientOptions.Builder.maxWaitTime(int)设置最大等待连接的线程阻塞时间
MongoClientOptions.Builder.connectTimeout(int)设置连接超时的毫秒。0是默认和无限
MongoClientOptions.Builder.socketTimeout(int)设置socket超时。0是默认和无限
还有很多,详细在MongoClientOptions类