1 MongoDB
1.1 MongoDB 概念
1.1.1 什么是 MongoDB
MongoDB 是在2007年由DoubleClick公司的几位核心成员开发出的一款分布式文档数据库,由C++语言编写。
目的是为了解决数据大量增长的时候系统的可扩展性和敏捷性。MongoDB要比传统的关系型数据库简单很多。
在MongoDB中数据主要的组织结构就是数据库、集合和文档
,文档存储在集合当中,集合存储在数据库中。
MongoDB中每一条数据记录就是一个文档,数据结构由键值(key=>value)对组成
。
文档类似于 JSON 对象,它的数据结构被叫做BSON
(Binary JSON)。
下表将帮助您更容易理解MongoDB中的一些概念:
RDBMS | MongoDB |
数据库 | 数据库 |
表格 | 集合 |
行 | 文档 |
列 | 字段 |
表联合 | 嵌入文档 |
主键 | _id |
1.2 安装和启动(docker方式)
1.2.1 拉取镜像
docker pull mongo:7.0.0
1.2.2 创建和启动容器
需要在宿主机建立文件夹
rm -rf /opt/mongo
mkdir -p /opt/mongo/data/db
docker run -d --restart=always -p 27017:27017 --name mongo -v /opt/mongo/data/db:/data/db mongo:7.0.0
1.2.3 进入容器
docker exec -it mongo mongosh
docker exec -it mongo-yapi mongo -- 现有的容器
1.2.4 基本命令
show dbs # 查看数据库
db.version() #当前db版本
db.getMongo() #查看当前db的链接机器地址
db.help() #帮助
quit() #退出命令行
1.3 客户端远程远程连接
软件 mongodb-compass-1.39.3-win32-x64.exe`,安装
客户端连接:
1.3.2 MongoDB适用场景
MongoDB不需要去明确指定一张表的具体结构,对字段的管理非常灵活,有很强的可扩展性。
支持高并发、高可用、高可扩展性,自带数据压缩功能,支持海量数据的高效存储和访问。
支持基本的CRUD、数据聚合、文本搜索和地理空间查询功能。
适用场景:
- 网站数据:Mongo非常适合实时的插入,更新与查询,并具备网站实时数据存储所需的复制及高度伸缩性。
- 高伸缩性的场景:Mongo非常适合由数十或数百台服务器组成的数据库。
- 大尺寸,低价值的数据:使用传统的关系型数据库存储一些数据时可能会比较昂贵,在此之前,很多时候程序员往往会选择传统的文件进行存储。
- 缓存:由于性能很高,Mongo也适合作为信息基础设施的缓存层。在系统重启之后,由Mongo搭建的持久化缓存层可以避免下层的数据源过载。
例如:
弹幕、直播间互动信息、朋友圈信息、物流场景等
不适用场合:
- 高度事务性系统:例如银行系统。传统的关系型数据库目前还是更适用于需要大量原子性复杂事务的应用程序。
- 传统的商业智能应用:针对特定问题的BI数据库会对产生高度优化的查询方式。对于此类应用,数据仓库可能是更合适的选择。
1.4 数据库操作
1.4.1 创建数据库
如果数据库不存在,则创建数据库,否则切换到指定数据库。
use tingshu
1.4.2 查看当前数据库
db.getName()
1.4.3 显示当前数据库状态
db.stats()
1.4.4 删除当前数据库
db.dropDatabase()
1.5 集合操作
1.5.1 创建集合
db.createCollection("User")
1.5.2 删除集合
db.User.drop()
1.6 文档操作
文档是一组键值(key-value)对。MongoDB 的文档不需要设置相同的字段,并且相同的字段不需要相同的数据类型,这与关系型数据库有很大的区别,也是 MongoDB 非常突出的特点。
需要注意的是:
1、MongoDB区分类型和大小写。
2、MongoDB的文档不能有重复的键。
1.6.1 insert
向User集合插入一条记录。可以预先使用createCollection方法创建集合,也可以不创建集合,直接插入数据,那么集合会被自动创建
db.User.insert({name:'zhangsan',age:21,sex:true})
1.6.2 query
查询当前User集合中所有的记录
db.User.find()
查询当前User集合中name是zhangsan的记录
db.User.find({name:"zhangsan"})
1.6.3 update
只更新匹配到的第一条记录
db.User.update({age:21}, {$set:{name:100}})
更新匹配到的所有记录
db.User.update({age:21}, {$set:{age:99}}, {multi: true})
1.6.4 remove
移除一个文档
db.User.remove(id)
移除所有文档
db.User.remove({})
**更多命令参考:**MongoDB 教程 | 菜鸟教程
2 SpringBoot集成MongoDB
spring-data-mongodb 提供了MongoTemplate
与MongoRepository
两种方式访问mongodb,MongoRepository操作简单,MongoTemplate操作灵活,我们在项目中可以灵活使用这两种方式操作mongodb。
2.1 集成spring-data-mongodb
2.1.1 搭建项目
1、创建项目:mongo_demo
2、导入pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.0.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.atguigu</groupId>
<artifactId>mongo_demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--mongodb-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
3、添加配置文件
application.properties
spring.data.mongodb.database=tingshu
spring.data.mongodb.host=192.168.200.130
spring.data.mongodb.port=27017
2.1.2 添加实体
package com.atguigu.mongo_demo.model;
import lombok.Data;
import org.bson.types.ObjectId;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
import java.util.Date;
@Data
@Document("user") //指定mongodb中的集合名字
public class User {
@Id
private ObjectId id;
private String name;
private Integer age;
private String email;
private Date createDate;
}
2.2 MongoRepository 类似于es的Repository
2.2.1 添加Repository类
package com.atguigu.mongo.repository;
import com.atguigu.mongo_demo.model.User;
import org.bson.types.ObjectId;
import org.springframework.data.mongodb.repository.MongoRepository;
public interface UserRepository extends MongoRepository<User, ObjectId> {
}
2.2.2 创建测试类
test目录创建测试类:MongoRepositoryTest
@SpringBootTest
public class MongoRepositoryTest {
@Autowired
private UserRepository userRepository;
@Test
public void testAdd(){
// User user = new User(ObjectId.get(),"张玉祥",18,"[email protected]",new Date());
// userRepository.insert(user);
User user = new User();
// 如果不给id的话,会自动添加
user.setName("小谷");
user.setAge(19);
user.setCreateDate(new Date());
userRepository.save(user);
// save和insert的区别:save会判断一下是不是新的,如果不是新的就会修改一下
}
@Test
public void testSearch(){
// 查询所有 select * from user;
// List<User> userRepositoryAll = userRepository.findAll();
// userRepositoryAll.stream().forEach(user -> System.out.println(user));
//带条件查询 select * from user where id = ?
// Optional<User> userOptional = userRepository.findById(new ObjectId("666ba149c7e7283417f4cdf1"));
// User user = userOptional.get();
// System.out.println(user);
//条件查询
// select * from user where name = ? and age = ?
// User user = new User();
// user.setAge(19);
// user.setName("张玉祥");
// Example<User> of = Example.of(user);
// userRepository.findAll(of).forEach(System.out::println);
//排序查询
// select * from user where name = ? and age = ? order by data desc
User user = new User();
user.setAge(19);
user.setName("张玉祥");
Example<User> example = Example.of(user);
System.out.println(userRepository.findAll(example, Sort.by(Sort.Direction.DESC, "createDate")));
// select * from user where name = ? and age = ? order by data desc limit 10
// 查询第几页 , 每页显示大小
PageRequest pageRequest = PageRequest.of(0, 2).withSort(Sort.by(Sort.Direction.DESC,"createDate"));
userRepository.findAll(example,pageRequest).forEach(System.out::println);
}
@Test
public void testUpdate(){
//因为没有update,但是save会判断一下是不是新的,如果不是新的就会修改一下
this.userRepository.save(new User(new ObjectId("dasdsadsadsad334234dsa"),"张玉玉祥",18,"[email protected]",new Date()));
}
@Test
public void testDelete(){
this.userRepository.deleteById(new ObjectId("dasdsadsadsad334234dsa"));
}
}
2.3 MongoTemplate
test目录创建测试类:MongoTemplateTest
@SpringBootTest
public class MongoTemplateTest {
@Resource
private MongoTemplate mongoTemplate;
@Test
public void add(){
User user = new User(ObjectId.get(),"大张玉祥",18,"[email protected]",new Date());
// mongoTemplate.save(user);
mongoTemplate.insert(user);
}
//查询所有
@Test
public void testFindUser() {
List<User> userList = mongoTemplate.findAll(User.class);
System.out.println(userList);
}
//根据id查询
@Test
public void testFindUserById(){
User user = mongoTemplate.findById("64eeeae31711344f35635788", User.class);
System.out.println(user);
}
//分页加排序查询
@Test
public void testFind(){
// select * from tname where name = ? order by createDate desc limit 1
Query query = new Query();
query.addCriteria(Criteria.where("name").is("张玉祥"))
.with(Sort.by(Sort.Direction.DESC,"createDate"))
.with(PageRequest.of(0,1));
System.out.println(mongoTemplate.find(query, User.class));
}
//修改
@Test
public void testUpdateUser() {
Criteria criteria = Criteria.where("name").is("张玉祥");
Query query = new Query(criteria);
Update update = new Update();
update.set("name", "zhangsan");
update.set("age", 99);
UpdateResult result = mongoTemplate.upsert(query, update, User.class);//改一条
//UpdateResult result = mongoTemplate.updateMulti(query, update, User.class);//改多条
long count = result.getModifiedCount();
System.out.println(count);
}
//删除
@Test
public void testRemove() {
Query query = new Query(Criteria.where("name").is("张玉祥"));
DeleteResult result = mongoTemplate.remove(query, User.class);
long count = result.getDeletedCount();
System.out.println(count);
}
//条件查询 and
@Test
public void findUserList() {
Criteria criteria = Criteria.where("name").is("test").and("age").is(20);
Query query = new Query(criteria);
List<User> userList = mongoTemplate.find(query, User.class);
System.out.println(userList);
}
//模糊查询
@Test
public void findUsersLikeName() {
// select * from album where album_name like 张*%
Criteria criteria = Criteria.where("name").regex("^张");
Query query = new Query(criteria);
List<User> userList = mongoTemplate.find(query, User.class);
System.out.println(userList);
}
}