MongoDB
一.NoSQL简介
NoSQL(Not Only SQL),指的是非关系型数据库,是一种全新的数据革命性运动.
- 为什么使用NoSQL
- 对数据库的高并发读写
- 对海量数据的高效率存储和访问
- 对数据库的高扩展性和高可用性
- 弱点
- 数据事务一致性需求
- 数据库的写实时性和读实时性需求
- 都复杂的SQL查询,特别是多表关联的查询
二.什么是MongoDB?
MongoDB 是由C++ 语言编写的,是一个基于分布式文件存储的开源数据系统.
在高负载的情况下,添加更多的节点,可以保证服务器的性能.
MongoDB旨在为WEB应用提供可扩展的高性能数据存储解决方案.
MongoDB将数据存储为一个文档,数据结构由键值对(key:value)组成.
MongoDB文旦类似于JSON对象,字段可以包含其他文档,数组及文档数组
{
name: “sue”,
age: 26
}
三.MongoDB特点
- MongoDB是一个面向文档存储的数据库,操作起来比较简单和容易
- 你可以在MongoDB记录设置任何属性的索引,来实现更快的排序
- 你可以通过本地或者网络创建数据镜像,这使得MongoDB有更强的扩展性
- 如果负载的增加(需要更多的存储空间和更强的处理能力),它可以分布在计算机网络中的其他节点上 这就是所谓的分片
- Mongo支持丰富的查询表达式.查询指令使用JSON形式的标记,可以轻易查询文档中内嵌的的对象及数组
- MongoDB使用update()命令可以完成实现替换完成的文档(数据)或者一些指定的数据字段
- MongoDB中的Map/reduce主要用来对数据进行批量处理和聚合操作
- Map和Reduce.Map函数调用emit(key,value)遍历集合中的所有记录,将key与value传给Reduce函数进行处理
- Map函数和Reduce函数是使用Javascript编写的,并可以通过db.runCommand或者mapreduce命令来执行MapReduce操作
- GridFS是MongoDB中的内置功能,可以用于存放大量小文件
- MongoDB允许在服务端执行脚本,可以用javascript编写某个函数,直接在服务端执行,也可以把函数的定义存储在服务端,下次直接调用即可
- MongoDB支持各种编程语言:Ruby,Python,Java,C++,C#等多种语言
- Mongo安装简单
四.MongoDB概念解析
SQL术语概念 | MongoDB术语概念 | 解释说明 |
---|---|---|
database | database | 数据库 |
table | collection | 数据库表/集合 |
row | document | 数据库记录行/文档 |
column | field | 数据字段/域 |
index | index | 索引 |
table join | 表连接,MongoDB不支持 | |
primary key | primary key | 主键,MongoDB自动将id设置为主键 |
-
常用操作
一个mongodb中可以建立多个数据库
注意: 区分大小写
-
查看命令提示: db.help()
-
切换/创建数据库
use test
-
查询所有数据库
show dbs
-
删除当前使用的数据库
db.dropDatabase()
-
查看当前使用的数据库
db.getName()
-
显示当前db状态
db.stats()
-
当前db版本
db.version()
-
查看当前db的链接机器地址
db.getMongo()
-
-
集合
集合就是MongoDB文档组,类似与RDBMS(关系型数据库管理系统:Relational Database Management System)中的表格
集合存在与数据中,集合没有固定的结构,这意味着你在对集合可以插入不同格式和类型的数据,但通常情况下我们插入集合的数据都会有一定的关联性
常用命令:
-
创建一个集合
db.createCollection(“collName”)
-
得到指定名称的集合
db.getCollection(“user”)
-
五.适用场景
适用场景
- 网站数据: Mongo 非常适合实时的插入,更新与查询,并具备网站实时数据存储所需的复制及高度伸缩性
- 缓存: 由于性能很高,Mongo 也适合作为信息基础设施的缓存层.在系统重启之后,由Mongo搭建的持久化缓存层可以避免下层的数据源过载
- 大尺寸,低价格的数据
- 高伸缩性的场景: Mongo 非常适合有数十或数百台服务器组成的数据库.Mongo的路线图中包含对Map Reduce弓摩的内置支持
- 用于对象机JSON数据的存储: Mongo的BSON数据格式非常适合文档化格式的存储机查询
不适合场景
- 高度事务性的系统:例如银行或会计系统.传统的关系型数目前还是更适用于需要大量原子性复杂程序的应用程序
- 传统的商业智能应用:针对特定问题的BI数据库会对产生高度优化的查询方式.对于此类应用,数据仓库可能是更合适的选择
六.MongoDB入门
常用操作
User为一个集合
Insert
db.User.save({name:“张三”,age:13})
Query
db.User.find({name:“张三”})
指定字段: db.User.find({name:“张三”},{‘name’:1,‘age’:1})
db.User.find().sort({age:1}) 1 为升序 -1 为降序
db.User.find().skip(0).limit(3) 分页查询
db.User.find({age:{$in:[12,26,32]}})
db.User.find({age:{$gt:20}}).count()
db.User.find({$or:[{age:21},{age:28}]})
Update
db.User.update({name:“张三”},{$set:{age:100,sex:0}})
Remove
用于删除单个文档或全部文档,删除后文档无法恢复
db.User.remove(id)
db.User.remove()
七.springBoot集成mongoDB
-
集成简介
spring-boot-starter-data-mongodb 提供了MongoTemplate 与 MongoRepository 两种访问mongodb, MongoRepository 操作简单,MongoTemplate操作灵活,我们在项目中看可以灵活的使用这两种操作方式mongodb,MongoRepository的缺点是不够灵活,MongoTemplate正好可以弥补不足
-
搭建环境
初始化工程
引入依赖
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!-- mongodb 依赖--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-mongodb</artifactId> </dependency> <dependency> <groupId>joda-time</groupId> <artifactId>joda-time</artifactId> <version>2.10.1</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> </dependencies>
添加配置
在application.properties文件添加配置
spring.data.mongodb.uri=mongodb://localhost:27017/test
基于MongoTemplate开发的CURD操作
建立对应实体类
@Data
@Document("User")
public class User {
@Id
private String id;
private String name;
private Integer age;
private String email;
private Date createTime;
}
@SpringBootTest
class MongoApplicationTests {
@Autowired
private MongoTemplate mongoTemplate;
@Test
void save() {
User user = new User();
user.setName("张三丰");
User save = mongoTemplate.save(user);
System.out.println(save);
}
@Test
void findAll() {
List<User> all = mongoTemplate.findAll(User.class);
all.forEach(System.out::println);
}
@Test
void findById() {
User user = mongoTemplate.findById("619f7c04240ff24aedbb6ede", User.class);
System.out.println(user);
}
@Test
void findByWhere() {
Query query = new Query(Criteria.where("name").is("李四").and("age").is("14"));
List<User> users = mongoTemplate.find(query, User.class);
users.forEach(System.out::println);
}
@Test
void findByLike() {
Pattern pattern = Pattern.compile("张"); // 正则表达式
Query query = new Query(Criteria.where("name").regex(pattern));
List<User> users = mongoTemplate.find(query, User.class);
users.forEach(System.out::println);
}
@Test
void findByPage() {
int pageNo = 1;
int pageSize = 3;
Query query = new Query();
long count = mongoTemplate.count(query, User.class);
List<User> users = mongoTemplate.find(
query.skip((pageNo-1)*pageSize).limit(pageSize)
, User.class);
System.out.println("总条数: "+ count);
users.forEach(System.out::println);
}
@Test
void update() {
User user = mongoTemplate.findById("61a074208f5ac032fe832c97", User.class);
user.setEmail("zhangsan@qq.com");
Update update = new Update();
update.set("age","13");
update.set("email","zhangsan@qq.com");
Query query = new Query(Criteria.where("id").is("61a074208f5ac032fe832c97"));
UpdateResult upsert = mongoTemplate.upsert(query, update, User.class);
System.out.println(upsert);
}
@Test
void delete() {
Query query = new Query(Criteria.where("id").is("61a074208f5ac032fe832c97"));
DeleteResult remove = mongoTemplate.remove(query, User.class);
System.out.println(remove);
}
}
基于MongoRepository开发的CURD操作
创建UserRepository
public interface UserRepository extends MongoRepository<User,String> {
}
@SpringBootTest
class MongoApplicationTests1 {
@Autowired
private UserRepository userRepository;
@Test
void save() {
User user = new User();
user.setName("田七");
user.setAge(17);
user.setEmail("tianqi@qq.com");
User save = userRepository.save(user);
System.out.println(save);
}
@Test
void findAll() {
List<User> all = userRepository.findAll();
all.forEach(System.out::println);
}
@Test
void findById() {
User user = userRepository.findById("61a077e04e18df5339bfc49b").get();
System.out.println(user);
}
@Test
void findByWhere() {
User user = new User();
user.setName("田七");
Example<User> example = Example.of(user);
List<User> all = userRepository.findAll(example);
all.forEach(System.out::println);
}
@Test
void findByLike() {
User user = new User();
user.setName("田");
ExampleMatcher exampleMatcher = ExampleMatcher.matching()
.withStringMatcher(ExampleMatcher.StringMatcher.CONTAINING)
.withIgnoreCase(true);
Example<User> example = Example.of(user,exampleMatcher);
List<User> all = userRepository.findAll(example);
all.forEach(System.out::println);
}
@Test
void findByPage() {
// Pageable page = PageRequest.of(1, 3, Sort.by(Sort.Direction.DESC,"age"));
Pageable page = PageRequest.of(1, 3);
Page<User> userPage = userRepository.findAll(page);
List<User> content = userPage.getContent();
content.forEach(System.out::println);
}
@Test
void update() {
User user = userRepository.findById("619f7c04240ff24aedbb6ede").get();
user.setAge(177);
User save = userRepository.save(user);
System.out.println(save);
}
@Test
void delete() {
User user = userRepository.findById("619f74a6458e30684937be2e").get();
userRepository.delete(user);
}
}