MongoDB Java Driver 是 MongoDB 的 Java 客户端开发包,即 Java 使用 MongoDB 的驱动包
一、准备工作
MongoDB安装教程:
Mongo-java-driver驱动包:https://github.com/mongodb/mongo-java-driver/releases
国内 mongodb-driver jar 下载地址:http://central.maven.org/maven2/org/mongodb/mongo-java-driver/
Maven坐标:http://mongodb.github.io/mongo-java-driver/3.5/driver/getting-started/installation/
<dependencies> <dependency> <groupId>org.mongodb</groupId> <artifactId>mongo-java-driver</artifactId> <version>3.5.0</version> </dependency> </dependencies>
Doc文档:http://mongodb.github.io/mongo-java-driver/3.5/javadoc/
在线查看源码:https://github.com/mongodb/mongo-java-driver
MongoDB对Java的相关支持、技术:http://mongodb.github.io/mongo-java-driver/
官方MongoDB Java驱动程序提供与MongoDB的同步和异步交互。
元素特征
BSON Lib
一个独立的BSON库,具有新的编解码器基础设施,可用于构建高性能编码器和解码器,无需中间地图实例。
MongoDB Driver
一个更新的Java驱动程序,其中包括传统的API以及符合新的跨驱动程序CRUD规范的新的通用MongoCollection界面。
MongoDB Async Driver
一种新的异步API,可以利用Netty或Java 7的AsynchronousSocketChannel快速和非阻塞IO。
Core Driver
MongoDB驱动程序和异步驱动程序都建立在新的核心库之上,任何人都可以使用它来构建替代或实验性高级API。
官方教程:http://mongodb.github.io/mongo-java-driver/3.5/driver/getting-started/quick-start/
二、连接数据库
将下载的驱动包,放在你的web项目中lib目录下
连接数据库,你需要指定数据库名称,如果指定的数据库不存在,mongo会自动创建数据库。
连接数据库的Java代码如下:
注意:以下所有代码中的close关闭连接方法为了阅读方便就放在了try中,这其实是不正规的,应该放在finally块中。
import com.mongodb.MongoClient;
import com.mongodb.client.MongoDatabase;
public class MongoDBJDBC {
public static void main( String args[] ){
try{
// 连接到 mongodb 服务
MongoClient client = new MongoClient( "localhost" , 27017 );
// 连接到数据库对象
MongoDatabase db = client.getDatabase("chengxumiao");
System.out.println("数据库连接成功");
// 关闭链接,释放资源
client.close();
}catch(Exception e){
System.err.println( e.getClass().getName() + ": " + e.getMessage() );
}
}
}本实例中 Mongo 数据库无需用户名密码验证。如果你的 Mongo 需要验证用户名及密码,可以使用以下代码:
import java.util.ArrayList;
import java.util.List;
import com.mongodb.MongoClient;
import com.mongodb.MongoCredential;
import com.mongodb.ServerAddress;
import com.mongodb.client.MongoDatabase;
public class MongoDBJDBC {
public static void main(String[] args){
try {
//连接到MongoDB服务 如果是远程连接可以替换“localhost”为服务器所在IP地址
//ServerAddress()两个参数分别为 服务器地址 和 端口
ServerAddress serverAddress = new ServerAddress("localhost",27017);
List<ServerAddress> addrs = new ArrayList<ServerAddress>();
addrs.add(serverAddress);
//MongoCredential.createScramSha1Credential()三个参数分别为 用户名 数据库名称 密码
MongoCredential credential = MongoCredential.createScramSha1Credential("username", "databaseName", "password".toCharArray());
List<MongoCredential> credentials = new ArrayList<MongoCredential>();
credentials.add(credential);
//通过连接认证获取MongoDB连接
MongoClient mongoClient = new MongoClient(addrs,credentials);
//连接到数据库
MongoDatabase mongoDatabase = mongoClient.getDatabase("databaseName");
System.out.println("Connect to database successfully");
} catch (Exception e) {
System.err.println( e.getClass().getName() + ": " + e.getMessage() );
}
}
}三、创建集合
我们可以使用 com.mongodb.client.MongoDatabase 类中的createCollection()来创建集合
public static void main(String[] args) {
try{
// 连接到 mongodb 服务
MongoClient client = new MongoClient( "localhost" , 27017 );
// 连接到数据库
MongoDatabase mongoDatabase = client.getDatabase("chengxumiao");
System.out.println("创建chengxumiao数据库成功");
mongoDatabase.createCollection("student");
System.out.println("集合创建成功");
// 关闭连接
client.close();
}catch(Exception e){
System.err.println( e.getClass().getName() + ": " + e.getMessage() );
}
}创建成功如下图,一个chengxumiao数据库,和一个student集合(表)
四、获取集合(表)
我们可以使用com.mongodb.client.MongoDatabase类的 getCollection() 方法来获取一个集合
import com.mongodb.MongoClient;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import org.bson.Document;
public class Demo {
public static void main(String[] args) {
try{
// 连接到 mongodb 服务
MongoClient client = new MongoClient( "localhost" , 27017 );
// 连接到数据库
MongoDatabase mongoDatabase = client.getDatabase("chengxumiao");
System.out.println("连接 chengxumiao 数据库成功");
MongoCollection<Document> collection = mongoDatabase.getCollection("student");
System.out.println("集合 student 选择成功");
// 关闭连接
client.close();
}catch(Exception e){
System.err.println( e.getClass().getName() + ": " + e.getMessage() );
}
}
}编译运行以上程序,输出结果如下:
Connect to database successfully 集合 test 选择成功
五、插入文档
我们可以使用com.mongodb.client.MongoCollection类的 insertMany() 方法来插入一个文档
import com.mongodb.MongoClient;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import org.bson.Document;
import java.util.ArrayList;
import java.util.List;
public class Demo {
public static void main(String[] args) {
try{
// 连接到 mongodb 服务
MongoClient client = new MongoClient( "localhost" , 27017 );
// 连接到数据库
MongoDatabase mongoDatabase = client.getDatabase("chengxumiao");
System.out.println("连接 chengxumiao 数据库成功");
MongoCollection<Document> collection = mongoDatabase.getCollection("student");
System.out.println("集合 student 选择成功");
//插入文档
/**
* 1. 创建文档 org.bson.Document 参数为key-value的格式
* 2. 创建文档集合List<Document>
* 3. 将文档集合插入数据库集合中 mongoCollection.insertMany(List<Document>) 插入单个文档可以用 mongoCollection.insertOne(Document)
* */
Document document = new Document("title", "MongoDB").
append("description", "database").
append("likes", 100).
append("by", "Anson");
List<Document> documents = new ArrayList<>();
documents.add(document);
collection.insertMany(documents);
System.out.println("文档插入成功");
// 关闭连接
client.close();
}catch(Exception e){
System.err.println( e.getClass().getName() + ": " + e.getMessage() );
}
}
}创建成功如下图所示
_id为自动创建
创建成功后,可以多创建几条数据进行测试,比如我又新增一条数据如下
Document document = new Document("name", "Anson").
append("age", 24).
append("sex", "男").
append("Job", "IT");六、检索所有文档
我们可以使用 com.mongodb.client.MongoCollection 类中的 find() 方法来获取集合中的所有文档。
此方法返回一个游标,所以你需要遍历这个游标。
import com.mongodb.MongoClient;
import com.mongodb.client.FindIterable;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoCursor;
import com.mongodb.client.MongoDatabase;
import org.bson.Document;
public class Demo {
public static void main(String[] args) {
try{
// 连接到 mongodb 服务
MongoClient client = new MongoClient( "localhost" , 27017 );
// 连接到数据库
MongoDatabase mongoDatabase = client.getDatabase("chengxumiao");
System.out.println("连接 chengxumiao 数据库成功");
MongoCollection<Document> collection = mongoDatabase.getCollection("student");
System.out.println("集合 student 选择成功");
//检索所有文档
/**
* 1. 获取迭代器FindIterable<Document>
* 2. 获取游标MongoCursor<Document>
* 3. 通过游标遍历检索出的文档集合
* 4. 关闭游标
* */
FindIterable<Document> findIterable = collection.find();
// 建立游标
MongoCursor<Document> mongoCursor = findIterable.iterator();
while(mongoCursor.hasNext()){
System.out.println(mongoCursor.next());
}
// 关闭游标
mongoCursor.close();
// 关闭连接
client.close();
}catch(Exception e){
System.err.println( e.getClass().getName() + ": " + e.getMessage() );
}
}
}获取数据如下
连接 chengxumiao 数据库成功
集合 student 选择成功
Document{{_id=59a2a59b7ecf4e07f1e2d618, title=MongoDB, description=database, likes=100, by=Anson}}
Document{{_id=59a2a6597ecf4e08028e7213, name=Anson, age=24, sex=男, Job=IT}}七、(分页)获取多个文档
public static void main(String[] args) {
try {
// 连接到 mongodb 服务
MongoClient client = new MongoClient("localhost", 27017);
// 连接到数据库
MongoDatabase mongoDatabase = client.getDatabase("chengxumiao");
System.out.println("连接 chengxumiao 数据库成功");
client.listDatabaseNames();
MongoCollection<Document> collection = mongoDatabase.getCollection("student");
System.out.println("集合 student 选择成功");
FindIterable<Document> findIterable = collection.find();
int pageNo = -1;
int pageSize = 2;
int record = pageNo * pageSize;
findIterable.sort(new BasicDBObject("age", -1)); // 倒序排序
findIterable.limit(pageSize); //限制返回条数
findIterable.skip(record); //跳过前面指定数量的数据
// 建立游标
MongoCursor<Document> mongoCursor = findIterable.iterator();
while(mongoCursor.hasNext()){
System.out.println(mongoCursor.next());
}
// 关闭游标
mongoCursor.close();
// 关闭连接
client.close();
} catch (Exception e) {
System.err.println(e.getClass().getName() + ": " + e.getMessage());
}
}以上是使用limit+skip方式实现的分页,对于小的数据量还可以,如果查询的是很大的数据,那么使用这种方式就有些力不从心了。
经过网上各种查找资料,寻师问道的,发现了一种速度足以把skip+limit组合分页甩出几条街的方法。
思路: 条件查询+排序+限制返回记录。边查询,边排序,排序之后,抽取第一次分页中的最后一条记录,作为第二次分页的条件,进行条件查询,以此类推....
八、获取单个文档
使用Bson条件表达式来查询单个对象
public static void main(String[] args) {
try{
// 连接到 mongodb 服务
MongoClient client = new MongoClient( "localhost" , 27017 );
// 连接到数据库
MongoDatabase mongoDatabase = client.getDatabase("chengxumiao");
System.out.println("连接 chengxumiao 数据库成功");
MongoCollection<Document> collection = mongoDatabase.getCollection("student");
System.out.println("集合 student 选择成功");
// 查询单个条件
Bson filter = new BasicDBObject("_id","59a2a6597ecf4e08028e7213");
// Bson filter = new BasicDBObject("_id", new ObjectId("59a2a6597ecf4e08028e7213"));
FindIterable<Document> findIterable = collection.find(filter);
// 建立游标
MongoCursor<Document> mongoCursor = findIterable.iterator();
while(mongoCursor.hasNext()){
System.out.println(mongoCursor.next());
}
// 关闭游标
mongoCursor.close();
// 关闭连接
client.close();
}catch(Exception e){
System.err.println( e.getClass().getName() + ": " + e.getMessage() );
}
}以上代码根据_id方式不能正确来获取数据,这是因为id值为ObjectId类型,需要修改成如下代码才能正确获取到值。
Bson filter = new BasicDBObject("_id", new ObjectId("59a2a6597ecf4e08028e7213"));如果使用的不是_id方式查询,比如使用name,就可以正常取到值
Bson filter = new BasicDBObject("name","Anson");如果使用一些比较运算符,可以使用类似如下操作,年龄大于20岁的对象
map.put("age", new BasicDBObject("$gt", 20)); // age>20多条件查询append方式
查询大于20岁,小于30岁的对象
map.put("age", new BasicDBObject("$gt", 20).append("$lte", 30));多条件查询map方式
当然,除了上面的使用单个条件作为查询,也是可以使用多条件查询的,比如下面代码创建一个map对象就可以正确取到值
Map<String, Object> map = new HashMap<>();
map.put("name","Anson");
map.put("age",24);
// 查询多条件
Bson filter = new BasicDBObject(map);九、更新文档
你可以使用 com.mongodb.client.MongoCollection 类中的 updateMany() 方法来更新集合中的文档。
public class Demo {
public static void main(String[] args) {
try{
// 连接到 mongodb 服务
MongoClient client = new MongoClient( "localhost" , 27017 );
// 连接到数据库
MongoDatabase mongoDatabase = client.getDatabase("chengxumiao");
System.out.println("连接 chengxumiao 数据库成功");
MongoCollection<Document> collection = mongoDatabase.getCollection("student");
System.out.println("集合 student 选择成功");
//更新文档 将文档中likes=100的文档修改为likes=200
collection.updateMany(Filters.eq("likes", 100), new Document("$set",new Document("likes",200)));
//检索所有文档
FindIterable<Document> findIterable = collection.find();
MongoCursor<Document> mongoCursor = findIterable.iterator();
while(mongoCursor.hasNext()){
System.out.println(mongoCursor.next());
}
// 关闭游标
mongoCursor.close();
// 关闭连接
client.close();
}catch(Exception e){
System.err.println( e.getClass().getName() + ": " + e.getMessage() );
}
}
}编译结果如下
连接 chengxumiao 数据库成功
集合 student 选择成功
Document{{_id=59a2a59b7ecf4e07f1e2d618, title=MongoDB, description=database, likes=200, by=Anson}}
Document{{_id=59a2a6597ecf4e08028e7213, name=Anson, age=24, sex=男, Job=IT}}十、删除文档
删除集合中的第一个文档:deleteOne(Bson查询条件)
删除所有符合条件的文档:deleteMany(Bson查询条件)
public static void main(String[] args) {
try{
// 连接到 mongodb 服务
MongoClient client = new MongoClient( "localhost" , 27017 );
// 连接到数据库
MongoDatabase mongoDatabase = client.getDatabase("chengxumiao");
System.out.println("连接 chengxumiao 数据库成功");
MongoCollection<Document> collection = mongoDatabase.getCollection("student");
System.out.println("集合 student 选择成功");
//删除符合条件的第一个文档
collection.deleteOne(Filters.eq("likes", 200));
//删除所有符合条件的文档
// collection.deleteMany(Filters.eq("likes", 200));
//检索查看结果
FindIterable<Document> findIterable = collection.find();
// 创建游标
MongoCursor<Document> mongoCursor = findIterable.iterator();
while(mongoCursor.hasNext()){
System.out.println(mongoCursor.next());
}
// 关闭游标
mongoCursor.close();
// 关闭连接
client.close();
}catch(Exception e){
System.err.println( e.getClass().getName() + ": " + e.getMessage() );
}
}十一、创建索引
MongoDB支持索引,并且给一个DBCollection添加索引非常简单,你只要指明需要创建索引的字段,然后指明其是升序(1)还是降序(-1)即可,比如在"age"上创建升序索引。
MongoCollection<Document> collection = mongoDatabase.getCollection("student");
System.out.println("集合 student 选择成功");
// 创建索引
String index_result = collection.createIndex(new BasicDBObject("age", 1));
System.out.println("创建索引成功:" + index_result);
// 查询索引列表
ListIndexesIterable<Document> indexesIterable = collection.listIndexes();
// 建立游标
MongoCursor<Document> indexCursor = indexesIterable.iterator();
while (indexCursor.hasNext()) {
System.out.println(indexCursor.next());
}
// 关闭游标
indexCursor.close();查询结果,创建数据库时,系统会默认建立一个_id的索引,上面代码中使用索引,又创建了一个age_1的索引,所以有两个。
创建索引成功:age_1
Document{{v=2, key=Document{{_id=1}}, name=_id_, ns=chengxumiao.student}}
Document{{v=2, key=Document{{age=1}}, name=age_1, ns=chengxumiao.student}}除了以上几个方法的示例入门,走进java操作mongodb的新大门,还有很多方法需要亲自去尝试。如下图,有时间可以练练手
其他关注点
有些时候你会看到类似于下面的代码片段,但是同样又能取到需要的执行结果
import com.mongodb.*;
public class Demo {
public static void main(String[] args) {
try {
// 连接到 mongodb 服务
MongoClient client = new MongoClient("localhost", 27017);
// 连接到数据库
DB clientDB = client.getDB("chengxumiao");
System.out.println("连接 chengxumiao 数据库成功");
client.listDatabaseNames();
DBCollection collection = clientDB.getCollection("student");
System.out.println("集合 student 选择成功");
DBCursor dbCursor = collection.find(); // 倒序排序查询;
int pageNo = 0;
int pageSize = 5;
int record = pageNo * pageSize;
dbCursor.sort(new BasicDBObject("age", -1));
dbCursor.limit(5); //限制返回条数.
dbCursor.skip(record); //跳过前面指定数量的数据
// 建立游标
while (dbCursor.hasNext()) {
System.out.println(dbCursor.next());
}
// 关闭游标
dbCursor.close();
// 关闭连接
client.close();
} catch (Exception e) {
System.err.println(e.getClass().getName() + ": " + e.getMessage());
}
}
}MongoDatabase 对应 DB
MongoCollection<Document> 对应 DBCollection
FindIterable<Document> 对应 DBCursor
仔细观察调用的源代码可以发现,其实以上的方法已经被逐步的淘汰掉了,我更推荐使用最新的方法。
参考阅读
未经允许请勿转载:程序喵 » MongoDB Java Driver 快速入门 —— 增删改查/分页操作(一)
程序喵