1.8 整合MongoDB

1.8.1 MongoDB简介

MongoDB(来自于英文单词“Humongous”,中文含义为“庞大”)是可以应用于各种规模的企业、各个行业以及各类应用程序的开源数据库。基于分布式文件存储的数据库。由C++语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。MongoDB是一个高性能,开源,无模式的文档型数据库,是当前NoSql数据库中比较热门的一种。
MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。他支持的数据结构非常松散,是类似json的bjson格式,因此可以存储比较复杂的数据类型。Mongo最大的特点是他支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引。
传统的关系数据库一般由数据库(database)、表(table)、记录(record)三个层次概念组成,MongoDB是由数据库(database)、集合(collection)、文档对象(document)三个层次组成。MongoDB对于关系型数据库里的表,但是集合中没有列、行和关系概念,这体现了模式自由的特点。
MongoDB 在实际应用中我们最常用到的是collection和gridFS两个功能,collection一般用于存储bjson数据,gridFS用于存储文件。

1.8.2 配置工程

在pox.xml文件中添加spring-boot-starter-data-mongodb引用

1
2
3
4
5

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>

application-dev.properties 增加mongoDB配置

1
2
3
4
5

#================== mongoDB 配置 ===================#
spring.data.mongodb.host=localhost
spring.data.mongodb.port=27017
spring.data.mongodb.database=test

开发机遇注解的配置类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

package com.zone7.demo.helloworld.config.mongodb;

import com.mongodb.client.gridfs.GridFSBucket;
import com.mongodb.client.gridfs.GridFSBuckets;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.MongoDbFactory;

/**
* MongoDB配置类
*
* @author zone7
* @date 2019/5/7
*/
@Configuration
public class MongoDbConfig {

@Autowired
private MongoDbFactory mongoDbFactory;

@Bean
public GridFSBucket gridFSBucket() {
return GridFSBuckets.create(mongoDbFactory.getDb());
}

}

1.8.3 案例开发

开发服务层代码,代码中引入三个对象,分别是 MongoTemplate 、GridFsTemplate、GridFSBucket,MongoTemplate主要用于操作mongodb的collection,GridFsTemplate和GridFSBucket主要操作mongodb的GridFS文件系统;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179

package com.zone7.demo.helloworld.sys.service.impl;

import com.mongodb.client.gridfs.GridFSBucket;

import com.mongodb.client.gridfs.GridFSDownloadStream;
import com.mongodb.client.gridfs.model.GridFSFile;
import com.zone7.demo.helloworld.config.exception.GlobalException;
import com.zone7.demo.helloworld.sys.pojo.SysUser;
import org.bson.types.ObjectId;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.mongodb.gridfs.GridFsResource;
import org.springframework.data.mongodb.gridfs.GridFsTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StreamUtils;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.List;

/**
* 描述:
* mongo
*
* @author zone7
* @date 2018/8/9 10:24
*/
@Service
public class MongoDBServiceImpl {
private static final Logger logger = LoggerFactory.getLogger(MongoDBServiceImpl.class);

@Autowired
private MongoTemplate mongoTemplate;

@Autowired
private GridFSBucket gridFSBucket;
@Autowired
private GridFsTemplate gridFsTemplate;

/**
* 保存对象
*
* @param user
* @return
*/
public void saveObj(SysUser user) {
logger.info("--------------------->[MongoDB save start]");
mongoTemplate.save(user);

}


/**
* 查询所有
*
* @return
*/
public List<SysUser> findAll() {
logger.info("--------------------->[MongoDB find start]");
return mongoTemplate.findAll(SysUser.class);
}

/***
* 根据id查询
* @param id
* @return
*/
public SysUser getById(String id) {
logger.info("--------------------->[MongoDB find start]");
Query query = new Query(Criteria.where("_id").is(id));
return mongoTemplate.findOne(query, SysUser.class);
}

/**
* 根据名称查询
*
* @param username
* @return
*/
public SysUser getBookByName(String username) {
logger.info("--------------------->[MongoDB find start]");
Query query = new Query(Criteria.where("username").is(username));
return mongoTemplate.findOne(query, SysUser.class);
}

/**
* 更新对象
*
* @param user
* @return
*/
public void update(SysUser user) {
logger.info("--------------------->[MongoDB update start]");
Query query = new Query(Criteria.where("_id").is(user.getId()));
Update update = new Update().set("password", user.getPassword())
.set("name", user.getName())
.set("updateTime", new Date());

//updateFirst 更新查询返回结果集的第一条
mongoTemplate.updateFirst(query, update, SysUser.class);
//updateMulti 更新查询返回结果集的全部
// mongoTemplate.updateMulti(query,update,SysUser.class);
//upsert 更新对象不存在则去添加
// mongoTemplate.upsert(query,update,SysUser.class);

}

/***
* 删除对象
* @param user
* @return
*/
public void delete(SysUser user) {
logger.info("--------------------->[MongoDB delete start]");
mongoTemplate.remove(user);

}

/**
* 根据id删除
*
* @param id
* @return
*/
public void deleteById(String id) {
logger.info("--------------------->[MongoDB delete start]");
//findOne
SysUser book = getById(id);
//delete
delete(book);
}


/**
* 保存文件
* @param input
* @param name
*/
public String saveFile(byte[] input,String name){
ObjectId objectId=gridFsTemplate.store(new ByteArrayInputStream(input) ,name);
String s = objectId.toString();
return s;
}

/**
* 加载文件
*
* @param id
* @return
*/
public byte[] loadFile(String id) {
try {
Query query = Query.query(Criteria.where("_id").is(id));
GridFSFile gfsFile = gridFsTemplate.findOne(Query.query(Criteria.where("_id").is(id)));

String filename = gfsFile.getFilename();

logger.info("加载mongodb gf 文件名:"+filename);

//打开流下载对象
GridFSDownloadStream downloadStream = gridFSBucket.openDownloadStream(gfsFile.getObjectId());
//获取流对象
GridFsResource gridFsResource = new GridFsResource(gfsFile, downloadStream);

return StreamUtils.copyToByteArray(gridFsResource.getInputStream());
}catch(IOException e){
logger.error("读取mongodb文件错误",e);
throw new GlobalException("读取mongodb文件错误",e);
}
}
}

开发一个控制层用于测试调用服务层。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63

package com.zone7.demo.helloworld.sys.controller;

import com.zone7.demo.helloworld.commons.response.ResponseData;
import com.zone7.demo.helloworld.sys.pojo.SysUser;
import com.zone7.demo.helloworld.sys.service.MongoDBService;
import com.zone7.demo.helloworld.sys.service.RabbitService;
import com.zone7.demo.helloworld.sys.vo.SysUserVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
*
* mongodb 测试Controller
* @Author: zone7
* @Date: 2019/06/17
* @Version 1.0
*/
@RestController
@RequestMapping("/mongo")
public class MongoDBController {
@Autowired
private MongoDBService mongoDBService;

@RequestMapping(value = "/save",method = RequestMethod.POST)
public ResponseData save(SysUserVo userVo){

SysUser user = SysUser.builder().build();

BeanUtils.copyProperties(userVo,user);
mongoDBService.saveObj(user);

return ResponseData.successMessage("保存成功");
}
@RequestMapping(value = "/findAll" )
public ResponseData save(){
List<SysUser> users = mongoDBService.findAll();

return ResponseData.success(users);
}


@RequestMapping(value = "/saveFile" )
public ResponseData saveFile(String content,String name){

String id = mongoDBService.saveFile(content.getBytes(),name);

return ResponseData.success(id);
}

@RequestMapping(value = "/loadFile" )
public ResponseData loadFile( String id){

byte[] content = mongoDBService.loadFile(id);

return ResponseData.success(new String(content));
}


}

接下来需要确保mongodb已经启动,然后启动工程,使用Postman进行测试:
mongo1
查看mongo数据库发现已经自动创建了一个collection并增加了一条信息:
mongo1
接着我们再继续测试剩下的几个接口:
加载所有对象
mongo1

保存文件,这里为了简化操作,使用字符串作为文件内容来进行测试。
mongo1
文件保存成功,我们打开mongo客户端可以查看到数据库多了一个fs的buckets
mongo1
最后我们再做一次加载文件测试
mongo1