全面学习MongoDB,在Spring Boot项目中整合 MongoDB
MongoDB 如今是最流行的 NoSQL 数据库,被广泛应用于各行各业中,很多创业公司数据库选型就直接使用了 MongoDB。MongoDB一经推出就受到了广大社区的热爱,可以说是对程序员最友好的一种数据库,下面我们来了解一下它的特性。
一、MongoDB简介
1.1 什么是MongoDB
MongoDB 是一个基于分布式文件存储的数据库。由 C++ 语言编写。旨在为 WEB 应用提供可扩展的高性能数据存储解决方案。它可以应用于各种规模的企业、各个行业以及各类应用程序的开源的非关系型数据库。
MongoDB的数据结构非常灵活,它可以随着应用程序的发展而灵活地更新。与此同时,它也为开发人员提供了许多传统数据库的功能:二级索引、完整的查询系统及数据一致性等。可以说是最像关系型数据库的非关系型数据库。MongoDB能够使企业更加具有灵活性和可扩展性,无论是创业公司、互联网企业或者是传统企业都可以通过MongoDB 来创建新的应用。
MongoDB具备高可扩展性、高性能和高可用性等非关系型数据库的特性,可以从单服务器部署扩展到大型、复杂的多数据中心架构。利用内存计算的优势, MongoDB 能够提供高性能的数据读写操作。 MongoDB的本地复制和自动故障转移功能使应用程序具有企业级的可靠性和操作灵活性。
1.2 MongoDB的特点
MongoDB 是一个面向文档存储的数据库,操作起来比较简单和容易。相比其它的数据库,MongoDB具有如下特点:
1、易扩展性,MongoDB使用分片技术对数据进行扩展,MongoDB能自动分片、自动转移分片里面的数据块,去掉了关系型数据库的关系型特性,数据之间没有关系。让每一个服务器里面存储的数据都是一样大小。这样就非常容易扩展。
2、高性能,Mongo非常适合实时的插入,保留了关系型数据库即时查询的能力,并具备网站实时数据存储所需的复制及高度伸缩性。
3、高伸缩性,Mongo非常适合由数十或数百台服务器组成的数据库,Mongo的路线图中已经包含对MapReduce引擎的内置支持。
4、存储动态性,相较于传统的数据库当要增加一个属性值的时,对表的改动比较大,mongodb的面向文档的形式可以使其属性值轻意的增加和删除。而原来的关系型数据库要实现这个需要有很多的属性表来支持。
5、速度与持久性,MongoDB通过驱动调用写入时,可以立即得到返回得到成功的结果(即使是报错),这样让写入的速度更加快,当然会有一定的不安全性,完全依赖网络。
1.3 MongoDB 相关概念
我们常说 MongoDB是最像关系数据库的非关系型数据库,在学习 MongoDB 之前我们先了解一些MongoDB的相关概念,并用关系数据库和 MongoDB 作一下对比,方便更清晰地认识它。
SQL 术语 | MongoDB 术语 | 说明 |
DataBase | DataBase | 数据库 |
Table | Collection | 数据库表/集合 |
Row | Document | 数据记录行/文档 |
Column | Field | 数据字段/域 |
index | index | 索引 |
Table joins | MongoDB 不支持 | |
primary key | primary key | 主键,MongoDB 自动将 _id字段设置为主键 |
如上表所示:MongoDB 和关系数据库一样有库的概念,一个MongoDB 可以有多个数据库, MongoDB 中的集合就相当于我们关系数据库中的表,文档就相当于关系数据库中的数据行,域就相当于关系数据库中的列, MongoDB也支持各种索引有唯一主键,但不支持表连接查询。
二、MongoDB安装
MonggoDB支持以下Windows,Linux等平台。同时也提供了C、C++、C# / .NET、Erlang、Java、Ruby、Go等语言的驱动客户端。
MonggoDB官网下载地址为:https://www.mongodb.com/download-center#community。下面我们以Centos 系统为例,演示MongoDB的安装。
注意,在安装前需要安装libcurl、openssl等依赖包。命令如下:sudo yum install libcurl openssl
。
2.1 下载
step1:这里使用wget在线下载安装,也可以通过上面的下载地址,手动下载安装包。
# 1.下载
wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel70-5.0.13.tgz
# 2.解压
tar -zxvf mongodb-linux-x86_64-rhel70-5.0.13.tgz
# 3.将解压包拷贝到指定目录
mv mongodb-linux-x86_64-rhel70-5.0.13 /usr/local/mongodb
2.2 创建数据库目录
默认情况下 MongoDB 启动后会初始化以下两个目录:
数据存储目录:/var/lib/mongodb
日志文件目录:/var/log/mongodb
所以,在启动前先创建这两个目录,命令如下:
sudo mkdir -p /var/lib/mongo
sudo mkdir -p /var/log/mongodb
sudo chown 777 /var/lib/mongo # 设置权限
sudo chown 777 /var/log/mongodb # 设置权限
2.3 创建配置文件
MongoDB的bin目录下创建一个mongodb.conf 文件,增加如下配置:
#touch mongodb.conf
port=27017 #端口
bind_ip=0.0.0.0 #默认是127.0.0.1
dbpath=/var/lib/mongo/ #数据库存放
logpath=/var/log/mongodb/mongod.log #日志文件
fork=true #设置后台运行
#auth=true #开启认证
MongoDB默认没有配置文件,需要我们手动创建配置文件。建议使用自定义配置文件,而不是默认配置。bind_ip 设置为0.0.0.0,否则Mongo服务只能本地连接,远程服务器会连接不上。
2.4 启动MongoDB服务
接下来启动 MongoDB 服务,命令如下:
cd /usr/local/mongodb/bin
mongod --config mongodb.conf
打开 /var/log/mongodb/mongod.log 文件看到以下信息,说明启动成功。
如果要停止 mongodb 可以使用以下命令:
mongod --config mongodb.conf --shutdown
三、MongoDB的基本操作
接下来,我们使用MongoDB后台客户端操作数据库。MongoDB Shell 是 MongoDB 自带的交互式 Javascript shell,用来对 MongoDB 进行操作和管理的交互式环境。
3.1 客户端连接
在MongoDB安装目录的下的 bin 目录下的mongo命令文件。使用./mongo
命令进入 MongoDB 后台后,它默认会链接到 test 数据库:
3.2 基本操作
MongoDB可以说是最像关系数据库的非关系数据库。一些命令和Mysql 比较类似。比如show databases查看数据库,use database 切换数据库等。
# 查询数据库
show databases
# 切换数据库,
use test
# 查询当前数据库下面的集合
show collections
# 创建集合
db.createCollection("集合名称")
# 删除集合
db.集合名称.drop()
# 删除数据库
db.dropDatabase() //首先要通过use切换到当前的数据库
MongoDB没有创建数据库的命令,提供了use 命令切换数据库,如果数据库不存在,则切换后,创建完机会后会自动创建数据库。如果你要创建一个新的数据库,使用use 命令切换到新数据库,然后创建collection 即可。
四、增删改查
接下来,我们介绍如何对MongoDB 的集合中数据进行增删改查等操作。MongoDB的数据结构和 JSON 基本一样。所有存储在集合中的数据都是 BSON 格式存储(一种类似 JSON 的二进制形式的存储格式,是 Binary JSON 的简称)。
4.1 新增(insert)
插入数据之前,需要创建collocation,这里使用db.createCollection("
userinfo
")
命令创建了userinfo集合。
#新增一条数据
db.userinfo.insert({name:"张三",age:25,gander:"男",address:'海淀区'})
#新增多条数据
db.userinfo.insert([{name:"张三",age:25,gander:"男",address:'海淀区'},{name:"李四",age:16,gander:"女",address:'昌平区'}])
4.2 删除(delete)
在 MongoDB 中,remove 和 deleteOne 以及 deleteMany 都用于删除文档记录。但是,remove 函数返回的删除的结果的 WriteResult,而 delete 函数返回的是 bson 格式。
其中 remove 是根据参数 justOne 来判断是删除所有匹配的文档记录还是仅仅删除一条匹配的文档记录,默认是删除所有的匹配的记录。
deleteOne 函数仅仅删除一条匹配的文档记录,而 deleteMany 函数是删除所有的匹配的文档记录。
# 全部删除
db.userinfo.deleteMany({})
# 删除age为25的一条数据
db.inventory.deleteOne( { age:25} )
# 删除年龄为16岁的全部数据
db.userinfo.deleteMany({age:16})
# remove 移除
db.userinfo.remove({'name':'王五'})
根据MongoDB的官方说明,remove() 方法已经过时了,现在官方推荐使用 deleteOne() 和 deleteMany() 方法。
4.3 修改(update)
MongoDB提供了 update() 方法来更新集合中的数据。update() 方法使用比较复杂,语法格式如下所示:
db.collection.update(
<query>,
<update>,
{
upsert: <boolean>,
multi: <boolean>,
writeConcern: <document>
}
)
参数说明:
query : update的查询条件,类似sql update语句后where查询条件。
update : update的对象和一些更新的操作(如$,$inc...)等,也可以理解为sql update查询内set 部分。
upsert : 可选,这个参数的意思是,如果不存在update的记录是否插入,true为插入,默认是false 不插入。
multi : 可选,mongodb 默认是false,只更新找到的第一条记录,如果这个参数为true,就把按条件查出来多条记录全部更新。
writeConcern :可选,抛出异常的级别。
下面,我们通过 update() 方法来更新一条数据:
db.userinfo.update({'name':'王五'},{$set:{'address':'房山区'}})
上面的示例中,通过update()方法将姓名(name)为‘王五’的用户的住址信息(address)改为‘房山区’。
4.4 查询(find)
MongoDB 使用 find() 方法查询显示文档数据。语法格式如下:db.collection.find(query, projection)
。
query 指定查询条件,类似sql select语句后的where条件,
projection 为指定返回的键。默认返回文档中所有键值。
# 查询全部
db.userinfo.find()
# pretty() 方法以Json格式化显示所有文档。
db.userinfo.find().pretty()
# 查询一条数据
db.userinfo.findOne()
# 限制返回条数
db.userinfo.find().limit(1)
4.5 运算符
我们在查询数据的时候,经常会在查询条件中遇到条件判断的情况。如:查询年龄大于18岁的所有人员。同样,MongoDB中也提供类类似的条件运算符,具体有如下几个:
(>) 大于 - $gt
(<) 小于 - $lt
(>=) 大于等于 - $gte
(<= ) 小于等于 - $lte
# 查询年龄大于20的全部人员
db.userinfo.find({age:{$gt:20}})
MongoDB同样也有运算符$in,查询是否在某个集合中,类似sql 中的in关键字。使用方式如下:
db.userinfo.find({age:{$in:[16,20]}})
4.6 排序&分页
MongoDB提供了sort() 方法对数据进行排序,通过参数指定排序的字段,并使用 1 和 -1 来指定排序的方式,其中 1 为升序排列,而 -1 是用于降序排列。语法格式为:db.collection.find().sort({key:1})
。
# 按年龄升序
db.userinfo.find({}).sort({age:1})
# 按年龄降序
db.userinfo.find({}).sort({age:-1})
MongoDB提供了skip()方法来跳过指定数量的数据,skip方法同样接受一个数字参数作为跳过的记录条数。语法格式为:db.collection.find().limit(NUMBER).skip(NUMBER)
。
#分页查询 跳过20条查询10条
db.c1.find({}).sort({age:1}).skip(20).limit(10)
如上所示,通过skip() 和limit() 方法,即可实现数据分页查询的功能。
五、Spring Boot 整合MongoDB
Spring Boot提供了MongoDB的组件:spring-boot-starter-data-mongodb ,它是 Spring Data 的一个子模块。熟悉Spring Boot的朋友应该知道,Redis、Elasticsearch、JPA等数据操作组件都在Spring Data下。所以,在Spring Boot中操作mongodb和操作其他的数据库基本是一样的。
spring-boot-starter-data-mongodb 核心功能是映射 POJO 到 Mongo的DBCollection 中的文档,并且提供 Repository 风格数据访问层。spring-bootstarter-data-mongodb 除了继承 Spring Data 的通用功能外,针对 MongoDB 的特性开发了很多定制的功能,让我们使用 Spring Boot 操作 MongoDB 更加简便。
Spring Boot 操作 MongoDB 有两种比较流行的使用方法,一种是将 MongoTemplate 直接注入到 Dao 中使用,一种是继承 MongoRepository, MongoRepository 内置了很多方法可直接使用。下面我们分别来介绍它们的使用。
5.1 MongoTemplate
MongoTemplate 提供了非常多的操作 MongoDB 方法,MongoTemplate 实现了MongoOperations 接口,此接口定义了众多的操作方法如 find、 findAndModify、findOne、 insert、 remove、 save、 update and updateMulti 等。并提供了Query、 Criteria and Update 等流式 API。
5.1.1添加依赖
首先创建Spring Boot项目spring-boot-starter-mongodb,在 pom 包里面添加 spring-boot-starter-data-mongodb 包引用,示例代码如下:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
5.1.2 添加MongoDB连接配置
修改application.properties配置文件,添加Mongo连接配置,具体如下:
spring.data.mongodb.uri=mongodb://192.168.78.101:27017/mongotest
mongodb默认没有账号密码,IP+端口+数据库就可以连接成功。如果mongodb配置了有账号密码,那连接字符串则需要增加相应的账号密码:
spring.data.mongodb.uri=mongodb://username:password@192.168.78.101:27017/mongotest
此外,如果MongoDB采用集群部署的方式,可以使用集群的配置方式,具体如下:
spring.data.mongodb.uri=mongodb://user:pwd@ip1:port1,ip2:port2/database
5.1.3 创建数据实体
public class UserEntity implements Serializable {
private static final long serialVersionUID = -3258839839160856613L;
private Long id;
private String name;
private Integer age;
private String gander;
private String address;
... 省略getter和setter方法
}
5.1.4 增删改查操作
首先,创建一个测试类:MongoTemplateTest,将 MongoTemplate 注入到测试类中。
public class MongoTemplateTest {
private MongoTemplate mongoTemplate;
}
然后,实现了UserEntity对象的增、删、改、查功能。
@Test
public void testSaveUser() {
UserEntity user=new UserEntity();
user.setId(1L);
user.setName("test1");
user.setAddress("通州区");
user.setAge(29);
user.setGander("男");
mongoTemplate.save(user);
}
@Test
public void updateUser(){
Query query=new Query(Criteria.where("id").is(1));
Update update= new Update().set("age", 20).set("address", "大兴区");
//更更新查询返回结果集的第⼀一条
UpdateResult result =mongoTemplate.updateFirst(query,update,UserEntity.class);
if(result!=null)
System.out.println(result.getMatchedCount());
}
@Test
public void findUserByUserName(){
Query query=new Query(Criteria.where("name").is("test1"));
UserEntity user = mongoTemplate.findOne(query , UserEntity.class);
System.out.println(user);
}
@Test
public void deleteUserById(){
Query query=new Query(Criteria.where("id").is(1L));
mongoTemplate.remove(query, UserEntity.class);
}
最后,运行单元测试类MongoTemplateTest,验证使用MongoTemplate操作MongoDB增删改查功能是否成功。
5.2 MongoRepository
熟悉Spring Data的同学应该对Repository比较熟悉。MongoRepository 继承于 PagingAndSortingRepository,而PagingAndSortingRepository则是继承于CrudRepository,这两个接口是所有Repository接口的父接口。所以MongoRepository 和前面 JPA、 Elasticsearch 的使用比较类似,都是 Spring Data 家族的产品,最终使
用方法也就和 JPA、 ElasticSearch 的使用方式类似。下面就来演示下MongoRepository的用法。
首先创建一个UserRepository接口,继承 MongoRepository,这样就可直接使用 MongoRepository 的全部内置方法。具体代码如下:
public interface UserRepository extends MongoRepository<UserEntity, Long> {
UserEntity findByName(String name);
}
然后,创建一个测试类:MongoRepositoryTest,将 UserRepository 注入到测试类中。使用 UserRepository 进行增、删、改、查功能测试。具体代码如下:
public class MongoRepositoryTest {
private UserRepository userRepository;
public void testSaveUser() {
UserEntity user=new UserEntity();
user.setId(1L);
user.setName("test1");
user.setAddress("通州区");
user.setAge(29);
user.setGander("男");
userRepository.save(user);
}
public void updateUser(){
UserEntity user=new UserEntity();
user.setId(1L);
user.setName("test1");
user.setAddress("通州区");
user.setAge(29);
user.setGander("男");
userRepository.save(user);
}
public void findUserByUserName(){
UserEntity user = userRepository.findByName("test1");
System.out.println(user);
}
public void deleteUserById(){
userRepository.deleteById(1L);
}
}
细心的同学已经发现了, MongoRepository 的使用方式和 Spring Boot JPA 的用法非常相似,其实 spring-boot-starter-data-mongodb 和 spring-boot-starter-data-jpa 都来自于 Spring Data,它们的实现原理基本一致,因此使用 Repository操作MongoDB 完全可以参考JPA 用法。
最后,运行单元测试类MongoRepositoryTest,验证使用MongoRepository操作MongoDB增删改查功能是否成功。
最后
以上,我们就把MongoDB的安装和使用 以及 如何在Spring Boot 项目中整合使用MongoDB介绍完了。MongoDB 如今是最流行的 NoSQL 数据库之一,被广泛应用于各行各业中,作为程序员必须熟练掌握