Mongodb 是属于文档型的非关系型数据库,是一种NoSQL的数据库。特点是高性能、易部署、易使用,存储数据非常方便。
Mongodb特点
- 面向集合存储,容易存储对象类型的数据。在MongoDB 中数据被分组存储在集合中,集合类似RDBMS 中的表,一个集合中可以存储无限多的文档
- 模式自由,采用无模式结构存储。在MongoDB 中集合中存储的数据是无模式的文档,采用无模式存储数据是集合区别于RDBMS 中的表的一个重要特征
- 支持完全索引,可以在任意属性上建立索引,包含内部对象。MongoDB的索引和RDBMS 的索引基本一样,可以在指定属性、内部对象上创建索引以提高查询的速度。除此之外,MongoDB 还提供创建基于地理空间的索引的能力
- 支持查询。MongoDB 支持丰富的查询操作,MongoDB 几乎支持SQL中的大部分查询
- 强大的聚合工具。MongoDB 除了提供丰富的查询功能外,还提供强大的聚合工具,如count、group 等,支持使用MapReduce 完成复杂的聚合任务
- 支持复制和数据恢复。MongoDB 支持主从复制机制,可以实现数据备份、故障恢复、读扩展等功能。而基于副本集的复制机制提供了自动故障恢复的功能,确保了集群数据不会丢失
- 使用高效的二进制数据存储,包括大型对象(如视频)。使用二进制格式存储,可以保存任何类型的数据对象
- 自动处理分片,以支持云计算层次的扩展。MongoDB 支持集群自动切分数据,对数据进行分片可以使集群存储更多的数据,实现更大的负载,也能保证存储的负载均衡
- 支持Perl、PHP、Java、C#、JavaScript、Ruby、C 和C++语言的驱动程序,MongoDB 提供了当前所有主流开发语言的数据库驱动包,开发人员使用任何一种主流开发语言都可以轻松编程,实现访问MongoDB 数据库
- 件存储格式为BSON(JSON 的一种扩展)。BSON 是对二进制格式的JSON 的简称,BSON 支持文档和数组的嵌套
- 可以通过网络访问。可以通过网络远程访问MongoDB 数据库
基本操作
- MongoDB 将数据存储为一个文档,数据结构由键值 (key=>value) 对组成
- MongoDB 文档类似于 JSON 对象,字段值可以包含其他文档、数组、文档数组
- 安装管理 Mongodb 环境
- 完成数据库、集合的管理
- 数据的增加、修改、删除、查询
名词
SQL术语/概念 | MongoDB术语/概念 | 解释/说明 |
---|---|---|
database | database | 数据库 |
table | collection | 数据库表/集合 |
row | document | 数据库记录行/文档 |
column | field | 数据字段/域 |
index | index | 索引 |
table joins | 表连接,MongoDB不支持 | |
primary key | primary key | 主键,MongoDB 自动将 _id 字段设置为主键 |
三元素:数据库、集合、文档
数据库:是一个集合的物理容器,一个数据库中可以包含多个文档
一个服务器通常有多个数据库
集合就是关系型数据库中的表
文档对应着关系数据库中的行
集合:类似于关系型数据库中的表,存储多个文档,结构不固定,如可以存储如下文档在一个集合中
{'name':'guojing', 'gender':'男'}
{'name':'huangrong', 'age':18}
{'book':'shuihuzhuan', 'heros':108}
文档,就是一个对象,由键值对构成,是 json 的扩展 Bson 形式
{'name':'JayChou', 'gender':'男'}
SpringBoot整合Mongodb实现CRUD操作步骤
1.引入mongodb依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
2.配置文件application.yml
spring:
data:
mongodb:
host: localhost
port: 27017
database: testdb
3.自定义实体类
@Document(collection = "user")
public class User {
@Id
private String id;
private String name;
private Integer age;
private String description;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}
4.数据访问层
@Repository
public interface UserDao extends MongoRepository<User, String> {
/**
* 根据年龄段来查找
*
* @param from from
* @param to to
* @return List<User>
*/
List<User> findByAgeBetween(Integer from, Integer to);
/**
* 通过年龄段,用户名,描述(模糊查询)
*
* @param from from
* @param to to
* @param name name
* @param description description
* @return List<User>
*/
List<User> findByAgeBetweenAndNameEqualsAndDescriptionIsLike(Integer from, Integer to, String name, String description);
/**
* 更具描述来模糊查询用户
*
* @param description 描述
* @return List<User>
*/
List<User> findByDescriptionIsLike(String description);
/**
* 通过用户名查询
*
* @param name 用户名
* @return List<User>
*/
List<User> findByNameEquals(String name);
}
5.服务层
@Service
public class UserService {
@Autowired
private UserDao userDao;
@Autowired
private MongoTemplate template;
public List<User> getUsers() {
return userDao.findAll();
}
public Optional<User> getUser(String id) {
return this.userDao.findById(id);
}
/**
* 新增和修改都是 save方法,
* id 存在为修改,id 不存在为新增
*/
public User createUser(User user) {
user.setId(null);
return userDao.save(user);
}
public void deleteUser(String id) {
this.userDao.findById(id)
.ifPresent(user -> this.userDao.delete(user));
}
public void updateUser(String id, User user) {
this.userDao.findById(id)
.ifPresent(
u -> {
u.setName(user.getName());
u.setAge(user.getAge());
u.setDescription(user.getDescription());
this.userDao.save(u);
}
);
}
public List<User> getUserByAge(Integer from, Integer to) {
return this.userDao.findByAgeBetween(from, to);
}
public List<User> getUserByName(String name) {
return this.userDao.findByNameEquals(name);
}
public List<User> getUserByDescription(String description) {
return this.userDao.findByDescriptionIsLike(description);
}
public Page<User> getUserByCondition(int size, int page, User user) {
Query query = new Query();
Criteria criteria = new Criteria();
if (!StringUtils.isEmpty(user.getName())) {
criteria.and("name").is(user.getName());
}
if (!StringUtils.isEmpty(user.getDescription())) {
criteria.and("description").regex(user.getDescription());
}
query.addCriteria(criteria);
Sort sort = new Sort(Sort.Direction.DESC, "age");
Pageable pageable = PageRequest.of(page, size, sort);
List<User> users = template.find(query.with(pageable), User.class);
return PageableExecutionUtils.getPage(users, pageable, () -> template.count(query, User.class));
}
}
6.控制层
@RestController
@RequestMapping("user")
public class UserController {
@Autowired
private UserService userService;
@GetMapping
public List<User> getUsers() {
return userService.getUsers();
}
@PostMapping
public User createUser(User user) {
return userService.createUser(user);
}
@DeleteMapping("/{id}")
public void deleteUser(@PathVariable String id) {
userService.deleteUser(id);
}
@PutMapping("/{id}")
public void updateUser(@PathVariable String id, User user) {
userService.updateUser(id, user);
}
/**
* 根据用户 id查找
* 存在返回,不存在返回 null
*/
@GetMapping("/{id}")
public User getUser(@PathVariable String id) {
return userService.getUser(id).orElse(null);
}
/**
* 根据年龄段来查找
*/
@GetMapping("/age/{from}/{to}")
public List<User> getUserByAge(@PathVariable Integer from, @PathVariable Integer to) {
return userService.getUserByAge(from, to);
}
/**
* 根据用户名查找
*/
@GetMapping("/name/{name}")
public List<User> getUserByName(@PathVariable String name) {
return userService.getUserByName(name);
}
/**
* 根据用户描述模糊查找
*/
@GetMapping("/description/{description}")
public List<User> getUserByDescription(@PathVariable String description) {
return userService.getUserByDescription(description);
}
/**
* 根据多个检索条件查询
*/
@GetMapping("/condition")
public Page<User> getUserByCondition(int size, int page, User user) {
return userService.getUserByCondition(size, page, user);
}
}
下面进行测试,先启动MongoDB Server
,再启动项目
POST http://localhost:8080/user?name=aaa&description=AAA&age=16
{
"id": "5ed612d3a4247e38d0b7e69a",
"name": "aaa",
"age": 16,
"description": "AAA"
}
POST http://localhost:8080/user?name=bbb&description=BBB&age=20
{
"id": "5ed612f4a4247e38d0b7e69b",
"name": "bbb",
"age": 20,
"description": "BBB"
}
POST http://localhost:8080/user?name=ccc&description=CCC&age=26
{
"id": "5ed61303a4247e38d0b7e69c",
"name": "ccc",
"age": 26,
"description": "CCC"
}
POST http://localhost:8080/user?name=ddd&description=DDD&age=30
{
"id": "5ed61313a4247e38d0b7e69d",
"name": "ddd",
"age": 30,
"description": "DDD"
}
GET http://localhost:8080/user
GET http://localhost:8080/user/5ec29af8a4247e0f00e53e00
PUT http://localhost:8080/user/5ed61313a4247e38d0b7e69d?description=HELLO&age=66
DELETE http://localhost:8080/user/5ec2a4e3a4247e0f00e53e03
GET http://localhost:8080/user/age/15/25
GET http://localhost:8080/user/name/ccc
GET http://localhost:8080/user/description/A
GET http://localhost:8080/user/condition?size=2&page=0