[SpringBoot][8][文档数据库MongoDB]

第 8 章 文档数据库MongoDB

对于那些需要缓存而且经常需要统计、分析和查询的数据,Redis这样简单的NoSQL显然就不是那么便捷了, 这时另外一个NoSQL就派上用场了,它就是本章的主题MongoDB。对于那些需要统计、按条件查询和分析的数
据,它提供了支持,它可以说是一个最接近于关系数据库的NoSQL

MongoDB是由C++语言编写的一种NoSQL,是一个基于分布式文件存储的开源数据库系统。在负载高时可以添加更多的节点,以保证服务器性能,MongoDB的目的是为Web应用提供可扩展的高性能数据存储解决方案。MongoDB将数据存储为一个文档,数据结构由键值(key-value)对组成。这里的MongoDB文档类似于JSON 数据集,所以很容易转化成为JavaPOJO对象或者JavaScript对象,这些字段值还可以包含其他文档、数组及文档数组。

8.1 配置MongoDB

SpringBoot提供了MongoDB的配置,其默认的可配置项如下所示

1
2
3
4
5
6
7
spring.data.mongodb.host=192.168.11.131 #MongoDB服务器
spring.data.mongodb.username=spring #MongoDB服务器用户名
spring.data.mongodb.password=123456 #MongoDB服务器密码
spring.data.mongodb.port=27017 #MongoDB服务器端口
spring.data.mongodb.database=springboot #数据库名称
spring.data.mongodb.repository.type=auto #是否启用MongoDB关于JPA规范的编程
spring.data.mongodb.field-naming-strategy=xxx #使用字段名策略

8.2 使用MongoTemplate实例

spring-data-mongodb主要是通过MongoTemplate进行操作数据。SpringBoot会根据配置自动生成MongoTemplate对象来操作数据,下面举个例子来说明

首先创建POJO

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
package com.springboot.chapter8.pojo;

import java.io.Serializable;
import java.util.List;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.mapping.Field;

// 标识为MongoDB文档
@Document
public class User implements Serializable {
private static final long serialVersionUID = -7895435231819517614L;
// MongoDB文档编号,主键
@Id
private Long id;
// 在MongoDB中使用user_name保存属性
@Field("user_name")
private String userName = null;

private String note = null;
// 角色列表
@DBRef
private List<Role> roles = null;
//setter and getter
}
  • 这个文档被标记为@Document,这说明它将作为MongoDB的文档存在。注解@id则将对应的字段设置为主键。@Field可以将属性userNameMongoDB中的user_name属性对应起来。然后角色列表,如果只想保存其引用,可以使用@DBRef进行标注

然后编写一个Service来看看MongoTemplate如何操作MongoDB文档

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
@Service
public class UserServiceImpl implements UserService {

// 注入MongoTemplate对象
@Autowired
private MongoTemplate mongoTmpl = null;

@Override
public User getUser(Long id) {
return mongoTmpl.findById(id, User.class);
// 如果只需要获取第一个也可以采用如下查询方法
// Criteria criteriaId = Criteria.where("id").is(id);
// Query queryId = Query.query(criteriaId);
// return mongoTmpl.findOne(queryId, User.class);
}

@Override
public List<User> findUser(String userName, String note, int skip, int limit) {
// 将用户名称和备注设置为模糊查询准则
Criteria criteria = Criteria.where("user_name").regex(userName).and("note").regex(note);
// 构建查询条件,并设置分页跳过前skip个,至多返回limit个
Query query = Query.query(criteria).limit(limit).skip(skip);
// 执行
List<User> userList = mongoTmpl.find(query, User.class);
return userList;
}

@Override
public void saveUser(User user) {
// 使用名称为user文档保存用户信息
mongoTmpl.save(user, "user");
// 如果文档采用类名首字符小写,则可以这样保存
// mongoTmpl.save(user);
}

@Override
public DeleteResult deleteUser(Long id) {
// 构建id相等的条件
Criteria criteriaId = Criteria.where("id").is(id);
// 查询对象
Query queryId = Query.query(criteriaId);
// 删除用户
DeleteResult result = mongoTmpl.remove(queryId, User.class);
return result;
}

@Override
public UpdateResult updateUser(Long id, String userName, String note) {
// 确定要更新的对象
Criteria criteriaId = Criteria.where("id").is(id);
Query query = Query.query(criteriaId);
// 定义更新对象,后续可变化的字符串代表排除在外的属性
Update update = Update.update("user_name", userName);
update.set("note", note);
// 更新单个对象
UpdateResult result = mongoTmpl.updateFirst(query, update, User.class);
// 更新多个对象
// UpdateResult result2 = mongoTmpl.updateMulti(query, update, User.class);
return result;
}

}
  • 注意: 在MongoDB中的save,若已存在id相同的对象,那么更新其属性;如果是已经存在的对象,则它只是对对象进行更新