目录
1.什么是NoSQL
什么是NoSQL数据库:全称"Not Only SQL"(非关系型数据库),其本质还是一种数据库技术,但是与关系型数据库对比,它不保证关系数据的ACID特性
优点:
- 满足对数据库的高并发读写
- 对海量数据高效存储和访问
- 对数据库高拓展性和高可用性
- 灵活的数据结构,满足数据结构不固定的场景
缺点:
- 一般不支持事物
- 实现复杂SQL查询,比较复杂;
- 运维人员数据维护门槛较高
- 目前不是主流的数据库技术
数据库特点对比
2.什么是MongoDB?
- 什么是MongoDB:一个以JSON为数据模型的文档的非关系型数据库;
- 为什么叫做文档数据库?一种非关系数据库,旨在将数据作为类 JSON 文档存储和查询
- 其用途?应用数据库,类似于Oracle,MySQL,专注于海量数据处理
- 特点:
- 建模灵活
- json数据模型
- 横向拓展简单
- 大数据量存储
- 高并发
- 是否开源:分为社区版:居于SSPL协议,开源; 企业版:居于商业协议,需要付费
2.MongoDB和RDBMS的区别
3.MongoDB优势
1.文档存储
数据存储以BSON/JSON文档,这对于Web应用程序有很大的意义, 建模方式自然而不失直观
2. 事务支持(目前只支持单文档的事务,对复杂的事务场景不支持)
3.高可用复制集(满足数据高可用、服务高可用的需求,运维简单,故障自动切换)
4.可扩展分片集群(海量数据存储,服务能力水平扩展)
5.建模灵活可拓展
- 多样性:同一个集合(表)异构数据(不同字段的文档对象)
- 动态性:需求变更,字段可更加需求动态拓展
- 数据治理:支持Json Schema规范,限制字段类型,在保证模型的灵活性前提下,保证数据安全
- API自然,快速开发
4.应用场景
- 游戏场景:使用MongoDB存储用户信息,装备,积分等,以内嵌文档的形式存储,方便查询更新
- 物流场景:存储订单信息,在运送过程中不断更新数据,以MongoDB内嵌数组的形式来存储,一次性将订单的信息查询出来
- 社交场景:存储用户数据,以及用户发表的朋友圈信息,童哥地理位置索引实现附件人,地点等功能
- 直播:存储用户信息,礼物信息等等;
不推荐使用场景:
- 对事物要求高的系统:银行,财务,金融累等系统,其MongoDB对事物支持较弱
- 对SQL要求较高的系统:特定问题的数据分析,多数据实体关联
- 涉及到复杂的,高度优化的查询方式
总结:
MongoDB能存储海量数据,但是要求一定查询性能的数据
3.MongoDB安装
Download MongoDB Community Server | MongoDB
进入MongoDB官网,看自己需求去下载对应得系统和版本,我使用得绿色方式
Windows安装版本有两种方式:
3.1:安装版本
小白双击安装,一路next即可
3.2.绿色版本
下载zip格式得压缩包
步骤一
解压在你想存放得磁盘中
步骤二:进入bin目录中,配置文件:mongo.conf
如果嫌每次启动得时候需要找,就创建一个启动脚本,以 .bat得格式,创建一个快捷方式
mongod --config ./mongo.conf
3.3:客户端
MongoDB客户端有非常多选择:
MongoVUE, RockMongo, Studio 3T, compass ,Navicat for MongoDB ,MongoDB shell
MongoDB Shell:MongoDB自带客户端
双击进入
也可以使用Navicat Premium 但是必需是 12及以上,这个可以去找其它大佬得破解教程
安装成功后进入 Navicat中,
连接成功后,默认是看不到数据库得需要点击查看:显示隐藏项目,才能看到MongoDB系统自带数据库
4.核心概念
核心:MongoDB是一个数据库再怎么都不会脱离数据库几个核心概念:数据库,表,列,行
SQL术语/概念 | MongoDB术语/概念 | 解释/说明 |
database | database | 数据库 |
table | collection | 数据库表/集合 |
row | document | 数据记录行/文档 |
column | field | 数据字段/域 |
index | index | 索引 |
table joins | 表连接,MongoDB不支持 | |
primary key | primary key | 主键,MongoDB自动将 _id字段设置为主键 |
怎样定义数据库名,集合名,字段名,跟之前MySQL定义数据库名,表名,列名遵循得规则一样
4.1 数据类型
5.MongoDB得使用
5.1使用MongoDB Shell 方式创建数据库
进入bin目录找到mongo.exe,双击进入控制界面
MongoDB没得专门创建数据库得命令,使用 use 选择某个数据库,不存在就会创建
删除数据库
- db.bropDatabase()//删除当前所在数据库
创建集合
- MongoBD中不用创建集合,主要是没得固定结构,直接使用db.createCollection("集合名称")
查看集合
show collections 或者 show tables
删除集合:db.集合名.drop();
5.2 Navicat方式
创建数据库
创建集合
注: MongoDB 语法使用JavaScript引擎进行解析的,如果你js学得还可以,那你就掌握了先手优势啦。其保存在桌面后缀为js
文档添加
语法:
- db.集合名.insert({文档})//插入单个
- db.集合名.insert({文档},{文档2})//插入多个
注:
- 集合新增文档时,集合不存在会自动创建集合
- 操作成功时,会为文档生成一个_id字段,但也可自定
案列
更新操作
语法:
- db.集合名.updateOne({query},{update})//更新单个
- db.集合名.updataMany({query},{update})//更新多个
query : update的查询条件,类似sql update查询内where后面的。
update : update的对象和一些更新的操作符(如$,$inc...)等,也可以理解为sql update查询内set后面的
练习
文档删除操作
语法:
- db.集合名.deleteOne({query})//单个删除
- db.集合名.deleteMany(query)}//删除多个
实列
文档查询
数据准备
db.task.insert({"id":NumberLong(1),"name":"九坔","age":NumberInt(18)})
db.task.insert({"id":NumberLong(2),"name":"九坔1","age":NumberInt(20)})
db.task.insert({"id":NumberLong(3),"name":"九坔是个帅哥","age":NumberInt(33)})
语法:
- db.集合名.find({query},{projection})
- query: 是条件
- projection: 列的投影,指定返回哪些列 id默认返回 eg: {"id": 0}
实列
排序
语法
db.集合名.find(query,projection)
sort({列:1} )//正序
sort({列:-1})//逆序
练习:
分页
语法:
db.集合名.find({}).skip(n).limit(m)
练习
db.users.find().skip((currentPage-1) * pageSize).limit(pageSize)//第n页
条件查询
比较运算符
语法:
db.集合.find( {逻辑操作符: [条件1, 条件2, ...]} )
比较操作符 | 解释 |
$and | && |
$or | || |
$not | ! |
练习:
逻辑运算符
语法:
db.集合.find( {逻辑操作符: [条件1, 条件2, ...]} )
比较操作符 | 解释 |
$and | && |
$or | || |
$not | ! |
>e | >= |
练习
模糊查询
语法:
db.集合.find({列: {$regex: /关键字/}}) //正则对象
db.集合.find({列: {$regex: "关键字"}}) //正则表达式
{name:/xxx/} --->%xxx%
{name:/^xxx/} --->xxx%
{name:/xxx$/} --->%xxx
{name:/xxx/i} 忽略大小写
练习
6. 文档设计
MongoDB文档设计跟普通的关系型数据库表设计类型,但是涉及到关联关系时,需要额外处理。
6.1文档嵌套
6.2数组方式
操作技巧:关系型数据库实体对象toJsonString之后就是MongoDB的数据文档
7.MongoDB集成进项目中
- 使用SpringBoot将MongoDB集成
基本的CRUD
需求:完成员工的基本CRUD
步骤1:创建项目,并且导入依赖
依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.3</version>
<relativePath/>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!--spring boot data mongodb-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
</dependencies>
步骤2: 配置mongoDB url
# application.properties
# 配置数据库连接
#格式: mongodb://账号:密码@ip:端口/数据库?认证数据库#spring.data.mongodb.uri=mongodb://root:admin@localhost/mongodemo?authSource=adminspring.data.mongodb.uri=mongodb://localhost/mongodemo
# 配置MongoTemplate的执行日志logging.level.org.springframework.data.mongodb.core=debug
步骤3:编写domain
@AllArgsConstructor
@NoArgsConstructor
@Setter
@Getter
@ToString
@Document("task") //设置文档所在的集合
public class Task{
//文档的id使用ObjectId类型来封装,并且贴上@Id注解,
// 自动映射为_id 自动封装ObjectId
//@Id 主键id,将id映射成集合中_id列
@Id
private String id;
private String name;
private Integer age;
private List<String> hobby = new ArrayList<>();
}
步骤4:编辑持久层接口
/**
* MongoDB自定义对象的持久层接口
* 1>定义接口继承MongoRepository
* 2>明确指定2个泛型
* 泛型1:当前接口操作实体对象:User
* 泛型2:当前接口操作实体对象对应主键属性类型:id
*/
public interface TaskMongoRepository extends MongoRepository<Task, String> {
}
步骤5: 编写 service 接口和实现类
public interface ITaskService {
//新增
void save(Task task);
//删除
void delete(String id);
//更新
void update(Task task);
//单个查寻
Task get(String id);
//查询全部
List<Task > list();
}
实现类
@Service
public class TaskServiceImpl implements ITaskService {
@Autowired
private TaskMongoRepository taskMongoRepository;
@Override
public void save(Task task) {
taskMongoRepository.save(task);
}
@Override
public void delete(String id) {
taskMongoRepository.deleteById(id);
}
@Override
public void update(Task task) {
taskMongoRepository.save(task);
}
@Override
public Task get(String id) {
return taskMongoRepository.findById(id).get();
}
@Override
public List<Task> list() {
return taskMongoRepository.findAll();
}
}
创建启动类
@SpringBootApplication
public class TaskServer {
public static void main(String[] args) {
SpringApplication.run(TaskServer.class,args);
}
}
测试类
@SpringBootTest
public class TaskServiceImplTest {
@Autowired
private ITaskService taskService;
@Test
public void testSave(){
Task task = new Task();
task.setName("dafei");
task.setAge(18);
taskService.save(task);
}
@Test
public void testUpdate(){
Task task = new Task();
task.setId("xxxx");
task.setName("九坔");
task.setAge(18);
taskService.update(task);
}
@Test
public void testDelete(){
taskService.delete("xxxx");
}
@Test
public void testGet(){
System.out.println(taskService.get("xxx"));
}
@Test
public void testList(){
System.out.println(taskService.list());
}
}
基本查询
需求:查询name = 九坔
方案一: JPA方式
书写好测试类
@SpringBootTest
public class FindNameTest {
@Autowired
private TaskRepository taskRepository;
//查询name = 九坔
@Test
public void findName() throws Exception{
Task task = taskRepository.findByName("九坔");
System.out.println("用户名= " + task);
}
}
在持久层添加方法
public interface TaskRepository extends MongoRepository<Task,String> {
//通过 name 查询数据
Task findByName(String name);
}
查询出结果
方案二:MongoTemplate方式
JPA查询语法针对简单条件查询还可以,但是涉及到高级查询(多条件查询)就不行了,所以使用Spring-data-mongodb 另外一套 api- MongoTemplate
@Test
public void testQuery2(){
//类似: mybatyis-plus 条件构造器--Wrapper
Criteria criteria = Criteria.where("name").is("九坔");
// 创建查询对象----MQL语句抽象对象
Query query = new Query();
// 添加限制条件
query.addCriteria(criteria);
List<Task> list = template.find(query, Task.class, "task");
list.forEach(System.err::println);
}
查询结果
分页查询
// 分页查询文档,显示第2页,每页显示3个,按照id升序排列
@Test
public void testQuery1() throws Exception {
// 创建查询对象
Query query = new Query();
// 设置分页信息
query.skip(3).limit(3);
// 设置排序规则
query.with(Sort.by(Sort.Direction.ASC,"id"));
List<Task> list = template.find(query, Task.class, "task");
list.forEach(System.err::println);
}
查询结果
总结:
- MongoDB就是一个以JSON为数据模型的文档的非关系型数据库
- 其基本的操作和关系型数据库差不多,但是进行高级查询的时候需要使用到MongoTemplate方式进行