MongoDB 概念
什么是 MongoDB
MongoDB 是在2007年由DoubleClick公司的几位核心成员开发出的一款分布式文档数据库,由C++语言编写。
目的是为了解决数据大量增长的时候系统的可扩展性和敏捷性。MongoDB要比传统的关系型数据库简单很多。
在MongoDB中数据主要的组织结构就是数据库、集合和文档
,文档存储在集合当中,集合存储在数据库中。
MongoDB中每一条数据记录就是一个文档,数据结构由键值(key=>value)对组成
。
文档类似于 JSON 对象,它的数据结构被叫做BSON
(Binary JSON)。
下表将帮助您更容易理解MongoDB中的一些概念:
RDBMS(关系型数据库) | MongoDB |
数据库 | 数据库 |
表格 | 集合 |
行 | 文档 |
列 | 字段 |
表联合 | 嵌入文档 |
主键 | _id |
安装和启动(docker方式)
拉取镜像
docker pull mongo:7.0.0
创建和启动容器
需要在宿主机建立文件夹
rm -rf /opt/mongomkdir -p /opt/mongo/data/dbdocker run -d --restart=always -p 27017:27017 --name mongo -v /opt/mongo/data/db:/data/db mongo:7.0.0
进入容器
docker exec -it mongo mongosh
基本命令
show dbs # 查看数据库
db.version() #当前db版本
db.getMongo() #查看当前db的链接机器地址
db.help() #帮助
quit() #退出命令行
客户端远程远程连接
MongoDB适用场景
MongoDB不需要去明确指定一张表的具体结构,对字段的管理非常灵活,有很强的可扩展性。
支持高并发、高可用、高可扩展性,自带数据压缩功能,支持海量数据的高效存储和访问。
支持基本的CRUD、数据聚合、文本搜索和地理空间查询功能。
适用场景:
- 网站数据:Mongo非常适合实时的插入,更新与查询,并具备网站实时数据存储所需的复制及高度伸缩性。
- 高伸缩性的场景:Mongo非常适合由数十或数百台服务器组成的数据库。
- 大尺寸,低价值的数据:使用传统的关系型数据库存储一些数据时可能会比较昂贵,在此之前,很多时候程序员往往会选择传统的文件进行存储。
- 缓存:由于性能很高,Mongo也适合作为信息基础设施的缓存层。在系统重启之后,由Mongo搭建的持久化缓存层可以避免下层的数据源过载。
例如:
弹幕、直播间互动信息、朋友圈信息、物流场景等
不适用场合:
- 高度事务性系统:例如银行系统。传统的关系型数据库目前还是更适用于需要大量原子性复杂事务的应用程序。
- 传统的商业智能应用:针对特定问题的BI数据库会对产生高度优化的查询方式。对于此类应用,数据仓库可能是更合适的选择。
数据库操作
数据库操作
创建数据库
如果数据库不存在,则创建数据库,否则切换到指定数据库。
use tingshu
查看当前数据库
db.getName()
显示当前数据库状态
db.stats()
删除当前数据库
db.dropDatabase()
集合操作
创建集合
db.createCollection("User")
删除集合
db.User.drop()
文档操作
文档是一组键值(key-value)对。MongoDB 的文档不需要设置相同的字段,并且相同的字段不需要相同的数据类型,这与关系型数据库有很大的区别,也是 MongoDB 非常突出的特点。
需要注意的是:
1、MongoDB区分类型和大小写。
2、MongoDB的文档不能有重复的键。
insert
向User集合插入一条记录。可以预先使用createCollection方法创建集合,也可以不创建集合,直接插入数据,那么集合会被自动创建
db.User.insert({name:'zhangsan',age:21,sex:true})
query
查询当前User集合中所有的记录
db.User.find()
查询当前User集合中name是zhangsan的记录
db.User.find({name:"zhangsan"})
update
只更新匹配到的第一条记录
db.User.update({age:21}, {$set:{name:100}})
更新匹配到的所有记录
db.User.update({age:21}, {$set:{age:99}}, {multi: true})
delete
删除一个文档
db.User.deleteOne({name:"lee"})
删除多个文档
db.User.deleteMany({ age: 21 })
删除所有文档(*)
db.User.remove({})
SpringBoot集成MongoDB
集成spring-data-mongodb
搭建项目
1.创建项目:mongo_demo
2.添加配置文件:
application.properties
spring.data.mongodb.database=mongodb_name
spring.data.mongodb.host=xx.xx.xx.xx
spring.data.mongodb.port=27017
添加实体
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 {@Idprivate ObjectId id;private String name;private Integer age;private String email;private Date createDate;
}
添加Repository类
import com.itcam.mongodbcase.model.User;
import org.bson.types.ObjectId;
import org.springframework.data.mongodb.repository.MongoRepository;public interface UserRepository extends MongoRepository<User, ObjectId> {}
测试MongoRepository
import com.itcam.mongodbcase.model.User;
import org.bson.types.ObjectId;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.*;import java.util.Date;
import java.util.List;
import java.util.Optional;@SpringBootTest
public class MongoRepositoryTest {@Autowiredprivate UserRepository userRepository;// 插入@Testpublic void testCreateUser() {User user = new User();user.setName("Lee");user.setAge(19);user.setEmail("cammy@163.com");user.setCreateDate(new Date());userRepository.save(user);}// 查询所有@Testpublic void testFindAll() {List<User> userList = userRepository.findAll();System.out.println("userList = " + userList);}// 根据id查询@Testpublic void testFindById() {Optional<User> optional = userRepository.findById(new ObjectId("671823c9224061033448a34f"));boolean present = optional.isPresent();if (present) {User user = optional.get();System.out.println("user = " + user);}}// 条件查询@Testpublic void testFindAllExample() {User user = new User();user.setAge(18);Example<User> example = Example.of(user);List<User> userList = userRepository.findAll(example);System.out.println("userList = " + userList);}// 排序条件@Testpublic void testFindAllSort() {Sort sort = Sort.by(Sort.Direction.DESC, "age");List<User> userList = userRepository.findAll(sort);System.out.println("userList = " + userList);}// 分页查询@Testpublic void testFindAllPage() {// 设置每页显示的条数// Pageable pageable = Pageable.ofSize(2);PageRequest pageRequest = PageRequest.of(0, 10);Page<User> page = userRepository.findAll(pageRequest);int totalPages = page.getTotalPages();List<User> userList = page.getContent();System.out.println("userList = " + userList);System.out.println("totalPages = " + totalPages);}// 更新@Testpublic void testUpdate() {// 先查询,再更新Optional<User> optional = userRepository.findById(new ObjectId("671823c9224061033448a34f"));if (optional.isPresent()) {User user = optional.get();user.setAge(99);// user中包含id,就会执行更新userRepository.save(user);System.out.println("user = " + user);}}// 删除@Testpublic void testDelete() {userRepository.deleteById(new ObjectId("671823c9224061033448a34f"));}
}
测试MongoTemplate
import com.itcam.mongodbcase.model.User;
import com.mongodb.client.result.DeleteResult;
import com.mongodb.client.result.UpdateResult;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
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 java.util.Date;
import java.util.regex.Pattern;@SpringBootTest
public class MongoTemplateTest {@Autowiredprivate MongoTemplate mongoTemplate;// 添加@Testpublic void testCreateUser() {for (int i = 0; i < 20; i++){User user = new User();user.setName("Cammy"+i);user.setAge(21);user.setEmail("cammy@163.com");user.setCreateDate(new Date());mongoTemplate.insert(user);}}// 查询所有@Testpublic void testFindAll() {mongoTemplate.findAll(User.class).forEach(System.out::println);}// 根据id查询@Testpublic void testFindById() {User user = mongoTemplate.findById("6718331e22e6386d283d783d", User.class);System.out.println("user = " + user);}// 修改@Testpublic void testUpdate() {Criteria criteria = Criteria.where("_id").is("6718331e22e6386d283d783d");Query query = new Query(criteria);Update update = new Update();update.set("age", 99);update.set("name","wukaiming");UpdateResult result = mongoTemplate.upsert(query, update, User.class); // 改一条// UpdateResult result = mongoTemplate.updateMulti(query, update, User.class); // 改多条long count = result.getModifiedCount();System.out.println("count = " + count);}// 删除@Testpublic void testRemove() {Criteria criteria = Criteria.where("_id").is("6718331e22e6386d283d783d");Query query = new Query(criteria);DeleteResult result = mongoTemplate.remove(query, User.class);long count = result.getDeletedCount();System.out.println("count = " + count);}// 条件查询 and@Testpublic void testFindByAnd() {Criteria criteria = Criteria.where("name").is("Lee").and("age").is(19);Query query = new Query(criteria);mongoTemplate.find(query, User.class).forEach(System.out::println);}// 模糊查询@Testpublic void testFindByLike() {// select * from album where album_name like ?%Pattern pattern = Pattern.compile("^Lee", Pattern.CASE_INSENSITIVE);Criteria criteria = Criteria.where("name").regex(pattern);Query query = new Query(criteria);mongoTemplate.find(query, User.class).forEach(System.out::println);}// 分页查询@Testpublic void testFindByPage() {Query query = new Query();// 查询总记录数long count = mongoTemplate.count(query, User.class);System.out.println("count = " + count);// 分页+排序PageRequest pageRequest = PageRequest.of(0, 10, Sort.by(Sort.Direction.ASC, "age"));query = new Query().with(pageRequest);// 分页查询mongoTemplate.find(query, User.class).forEach(System.out::println);}}