内容简介:使用 Java 8 学习 MongoDB(Part 1)
Java 8 提供了很多工具,能让你连接 MongoDB,查询数据,甚至转换结果。
欢迎来到新的系列教程:使用 Java 8 学习 MongoDB。通过这份教程,希望大家对 Java 8 提供的大数据和新特性有基本的概念,同时我们会在本教程广泛使用这些新特性。
在这篇文章里面,我们将会学习:
-
什么是 MongoDB
-
如何安装 MongoDB
-
如何在 MongoDB 中创建一个集合
-
如何在集合中插入文档
-
如何编写一个简单的 Java 程序连接 MongoDB,并从 Mongo 集合中查找某一个值
下面是一些关于 MongoDB 的简单介绍。
MongoDB
MongoDB 是一种 NoSQL 类型的数据库。数据按照 BSON 格式进行存储,所有的数据按照键/值对(key/value)的方式进行存储。其中 key 表示属性,value 表示相对于 key 存储的属性值。
Documents
在 Mongo 里面,文档代表着一种能存储任意数量的键值对的数据结构。比如 “员工” 数据可以表示为一个文档,其中 name,address,age 和它们的值以键值对(key-value)的方式存储在该文档中。要注意的是,文档存储为一种二进制 JSON 格式,称为 BSON (Binary JSON)。
下面是一个文档的例子:
{ "_id": { "$oid" : "58eb8c2b1de2b36bfcc74326" }, "name": "Shamik Mitra" }
在 Mongo 中,经常把具有相同数据结构的文档放入一个容器,并将其称为集合。可以把集合视为关系数据库中的表,每一行数据其实就对应着一个文档。所以我们可以认为 Employee 集合包含了多个 Employee 文档。不过要注意的是,这只是逻辑上面的一种理解。按照定义,一个集合可包含任意类型的文档 — 例如,一个集合能包含 Employee 文档以及 Car 文档。这些数据结构是没有约束的。
注意:在设计数据结构的时候,创建的集合最好与文档有着相似的结构。
无模式(No Schema)
这是 SQL 和 NoSQL 数据库之间的主要区别之一。对我而言,我不喜欢这些术语。我更倾向于使用关系数据库和非关系数据库来描述他们。使用 NoSQL,不需要任何预定义的模式 — 它能包含任何 BSON 格式的数据。具体来说,任何数据结构都适用于无模式数据库,因此它适用于存储非结构化的数据。
这使得开发者能更容易的进行开发,因为在关系型数据库中, 所有的数据都有一个固定的模式。比如一张员工表中有 name, age 和 address 字段,它存储的数据都保持着相同的数据结构。如果现在需要修改结构,比方说我们想要添加一个 gender 属性,则必须要改变表的模式以纳入新的属性。但是在 Mongo 中,因为它是模式自由的,所以这些都不需要,我们可将任何数据结构和任意属性的组合放在一起,可存储任意格式的数据。
注意:虽然 MongoDB 是模式自由的,但在设计的过程中,逻辑上我们把相同结构的文档放到一个集合中,所以会存在一个隐形的模式。
横向扩展
大数据的成功依赖于它的横向扩展能力。Mongo 作为大数据技术的一部分,当然也是支持的。通过横向扩展,MongoDB 能够将数据分发到多个节点上,每个节点都可以是低配的电脑,我们也可以轻松地添加和删除这些节点。所以当我们需要存储更多的数据时,可以添加新的节点而不影响现有的架构,然而在纵向扩展中(例如 RDBMS 使用的方式),我们则需要一台超级计算机,并且数据采用中央化存储的方式。
注意:在向多节点分发数据的时候,Mongo 有一定的容错机制。如果一个节点挂掉了之后,我们会使用其他的节点获取数据。当然,如果使用纵向扩展,因为数据是中央化存储,如果出现故障的话,我们会丢失所有的数据,这将会导致单点故障。
分片(Sharding)
分片是 MongoDB 将庞大的数据块拆分成小的数据块的技术,之后,它会为每个块创建一份副本,然后这些块会被分发到多个节点中。当查询时,服务器通过元数据查询到数据所在的节点,然后从该节点返回查询结果。
Mongo 安装步骤
-
下载最新的 Mongo ZIP 包( 下载地址 )
-
创建目录 D:\InstalledApps ,解压 ZIP 的文件到这个目录
-
将解压的文件夹重命名为 mongodb
-
在 mongodb 文件夹下新建 data 文件夹: D:\InstalledApps\mongodb\data
-
打开 cmd(命令行),输入以下命令:
cd D:\InstalledApps\mongodb\bin
进入 D:\InstalledApps\mongodb\bin -
通过命令启动 MongoDB Server:
mongod.exe --dbpath D:\InstalledApps\mongodb\data
MongoDB Server 启动在 localhost:27017
安装 Mongo 客户端
我们将会使用 RoboMongo 作为 mongo 客户端。它有漂亮的图形化界面,所以我们可以轻松创建集合,并通过使用 RoboMongo GUI 添加文档。
RoboMongo 下载地址( 戳这里 ),解压 ZIP 文件后,双击 RoboMongo.exe 运行程序。它将启动 RoboMongo GUI 。
通过下面的步骤连接到 Mongo Server:
-
Host: localhost 和 port: 27017。
-
创建数据库:在 RoboMongo 图形化界面中,右键点击右侧面板的 计算机图标 以创建一个数据库。使用 test 作为数据库的名字。
-
创建集合:右键点击右侧面板的 集合图标 。创建一个新的集合,命名为 Employee 。
-
插入一个文档:右键单击 Employee 集合,然后点击 Insert Document ,在文本区域粘贴以下内容:
{ "name" : "Shamik" , "address" : "1 Nivedita Lane" , "age" : 32}
点击 save ,这将在 Mongo Server 中插入文档。
这些操作其实也可以通过 Mongo 的控制台来完成。
编写 Java 代码
上述的步骤完成后,就该写 Java 代码连接 MongoDB 数据库了。要用到的 工具 有:
-
Eclipse Neon
-
适用于 Eclipse 的 Maven 插件
-
Java 8
第一步
首先,在 Eclipse 里创建一个名为 mongoExample 的 Maven 项目,并将 Java 编译器版本设置为 1.8。没有的话请去网上下载。
第二步
编写一个 pom.xml,如下所示:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>mongoExample</artifactId> <version>0.0.1-SNAPSHOT</version> <dependencies> <dependency> <groupId>org.mongodb</groupId> <artifactId>mongo-java-driver</artifactId> <version>2.10.1</version> </dependency> </dependencies> </project>
可以看到我们用了 mongo-java-driver 这个库配合 Java 8 来连接 Mongo Server。
创建 MongoContext 类
接下来,我们使用 Java 代码连接 Mongo Server。我们先写一个顶级 API 类,把连接 MongoDB Server 的操作抽象出来,并给调用者提供一些辅助方法:
/** * */ package com.example.config; import java.net.UnknownHostException; import java.util.function.Function; import com.mongodb.BasicDBObject; import com.mongodb.DB; import com.mongodb.DBCollection; import com.mongodb.DBCursor; import com.mongodb.MongoClient; /** * @author Shamik Mitra * */ public class MongoContext { private static MongoContext ctx = new MongoContext(); private MongoClient client; private DB db; private MongoContext(){ try{ init(); }catch(Exception ex){ ex.printStackTrace(); } } private void init() throws UnknownHostException{ this.client = new MongoClient("localhost" , 27017); } public static MongoContext get(){ return ctx; } public MongoContext connectDb(String dbname){ if(db !=null){ throw new RuntimeException("Already conected to " + db.getName() + "can't connect " + dbname); } this.db = client.getDB(dbname); System.out.println("DB Details :: " + db.getName()); return ctx; } public <T,X> DBCursor findByKey(String collectionName,String key,T value,Function<T,X> convertDataType){ DBCollection collection = db.getCollection(collectionName); BasicDBObject searchQuery = new BasicDBObject(); searchQuery.put(key, convertDataType.apply(value)); System.out.println("search Query ::" + searchQuery); DBCursor cursor = collection.find(searchQuery); return cursor; } }
代码说明
在代码中,我创建了一个单例对象 MongoContext。它的 init 方法会创建一个 MongoClient 类来连接 MongoDB。注意 MongoClient 类来自 Mongo Java Driver 这个库: this.client = new MongoClient("localhost" , 27017);
然后,我定义了静态的 get() 方法来返回类内部维护的 MongoContext 单例对象。
至此,成功建立了到 Mongo server 的连接。
下一步,指定需连接的数据库。我写了个 泛型方法 connectDb(String dbName ),调用它就可以指定要连接到的数据库。注意这个方法返回的类型是类的单例对象 MongoContext 本身。这里我用了链式代码的风格( Fluent API )来写。
下一步,从数据库中查询到我们需要的文档。
为此,我写了个 泛型方法 :
public <T,X> DBCursor findByKey(String collectionName,String key,T value,Function<T,X> convertDataType)
方法接受四个参数:
collectionName:代表要查询的集合名称,比如现在我们要查询的就是 Employee 集合。记住,可把集合看作关系型数据库里的表。
key:代表要从集合里查询的键,相当于在 SQL where 查询子句里指定的字段名。
value:代表键所对应的值,同样相当于 where 里给的值。
Function<T,X>:这里运用了 Java 8 的函数接口,可以把数据从一个类型 T 转换成另一个类型 X 。 ( T -> X) 。我们的这个泛型方法 findbyKey 需要用到这东西。
然而,现在的情况是,我们并不知道调用者到底想查询什么键,于是就会比较麻烦。例如说,在 Employee 集合里,员工姓名这个键是 字符串类型 ,而年龄是 整型 。如果调用者想以姓名来查询,那对应的数据类型就得是字符串,同理查询年龄就得用整型。因此,我们得用一种特殊方法,能把提供的值转换成对应的类型。现在呢,我们用 Lambda 表达式来实现我们的需求。可以看一下 这篇文章 ,了解到底什么是 Lambda 表达式。
在方法内,我们得到了要查询的集合名称,然后创建了 BasicDataObject 类的一个对象 searchQuery 。随后,把参数里的键和值提供给对象来提供查询信息。最后,我们执行查询,并把得到的查询结果放进一个 DBCursor 对象里以进行维护。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。