MongoDB Java Driver 快速入门 —— 增删改查/分页操作(一)

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

仔细观察调用的源代码可以发现,其实以上的方法已经被逐步的淘汰掉了,我更推荐使用最新的方法。

参考阅读

MacOS系统中MongoDB安装与启动

MongoDB常用语句


赞(52) 打赏
未经允许不得转载:优客志 » 数据库
分享到:

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏