MongoDB

MongoDB简介

对于社交类软件的功能特点:
  数据量会随着用户数增大而增大
  读多写少
  价值较低
  非好友看不到其动态内容
  地理位置的查询
  ……
针对以上特点,我们来分析一下:
  mysql:关系型数据库(效率低)
  redis:redis缓存(微博,效率高,数据格式不丰富)
  对于数据量大而言,显然不能够使用关系型数据库进行存储,我们需要通过MongoDB进行存储
  对于读多写少的应用,需要减少读取的成本
    比如说,一条SQL语句,单张表查询一定比多张表查询要快
数据库应用:
  mongodb:存储业务数据(圈子,推荐的数据,小视频数据,点赞,评论等)
  redis:承担的角色是缓存层(提升查询效率)
  mysql:存储和核心业务数据,账户

MongoDB简介

MongoDB是一个开源、高性能、支持海量数据存储的文档型数据库
是NoSQL数据库产品中的一种,是最像关系型数据库(MySQL)的非关系型数据库(不支持表关系:只能操作单表)
MongoDB是一个基于分布式文件存储的数据库。由C++语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。
MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的,它支持的数据结构非常松散,是类似json的bson格式,因此可以存储比较复杂的数据类型。
MongoDB最大的特点是它支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引。
官网:https://www.mongodb.com

MongoDB的特点

数据存储:内存 + 磁盘

高扩展性:内置数据分片

MongoDB与Redis和Mysql的对比

与Redis的对比
  Redis纯内存数据库,内存不足触发淘汰策略
  结构化存储格式(Bson),方便扩展
与MySQL的对比
  MongoDB不支持事务和多表操作
  MongoDB支持动态字段管理
查询效率对比
  Redis > MongoDB > MySQL

Mongodb的适用场景

游戏装备数据、游戏道具数据
  特征:修改频度较高
物流行业数据
  特征:地理位置信息,海量数据
直播数据、打赏数据、粉丝数据
  特征:数据量大,修改频度极高
日志数据
  特征:数据量巨大,结构多变

体系结构与术语

数据格式

MongoDB中使用Bson存储数据( Binary JSON ),一种类似Json的数据格式。

docker安装MongoDB

拉取镜像

docker pull mongo

创建容器

docker run --name mongo-service -p 27017:27017 -v ~/data/mongodata:/data -d  mongo

注:
  虚拟机中已经以docker-compose的形式提供了MongoDB容器。不需要重新拉取部署
  企业中MongoDB往往需要配置操作用户密码
启动容器

#进入base目录
cd /root/docker-file/base/
#批量创建启动容器,其中已经包含了redis,zookeeper,mongodb容器
docker-compose up -d
#查看容器
docker ps -a

mongoDB已经启动,对外暴露了27017的操作端口

MongoDB入门

基础命令

数据库操作

1 #查看所有数据库
2 show dbs 
3 #通过use关键字切换数据库
4 use testdb
5 #删除数据库
6 db.dropDatabase()

新增数据

在MongoDB中,存储的文档结构是一种类似于json的结构,称之为bson(全称为:Binary JSON)

#语法:db.表名.insert(json字符串)
> db.user.insert({id:1,username:'zhangsan',age:20})
> db.user.find()  #查询数据

修改数据

db.collection.update(
   <query>,
   <update>,
   [
     upsert: <boolean>,
     multi: <boolean>,
     writeConcern: <document>
   ]
)

注:
query : update的查询条件,类似sql update查询内where后面的。
update : update的对象和一些更新的操作符(如$,$inc.$set)等,也可以理解为sql update查询内set后面的
upsert (默认false ) : 可选,如果不存在update的记录,是否插入新数据,true为插入,默认是false,不插入。
multi(默认false ) : 可选,默认是false,只更新找到的第一条记录,如果这个参数为true,就把按条件查出来多条记录全部更新。
writeConcern :可选,抛出异常的级别。

#查询全部
> db.user.find()

#更新数据
> db.user.update({id:1},{$set:{age:22}}) 

#更新不存在的数据,默认不会新增数据
> db.user.update({id:3},{$set:{sex:1}})

#如果设置第一个参数为true,就是新增数据
> db.user.update({id:3},{$set:{sex:1}},true)

删除数据

db.collection.remove(
   <query>,
   {
     justOne: <boolean>,
     writeConcern: <document>
   }
)

注:
query :(可选)删除的文档的条件。
justOne: (可选)如果设为 true 或 1,则只删除一个文档,如果不设置该参数,或使用默认值 false,则删除所有匹配条件的文档。
writeConcern :(可选)抛出异常的级别。

#插入4条测试数据
db.user.insert({id:1,username:'zhangsan',age:20})
db.user.insert({id:2,username:'lisi',age:21})
db.user.insert({id:3,username:'wangwu',age:22})
db.user.insert({id:4,username:'zhaoliu',age:22})

> db.user.remove({age:22},true)

#删除所有数据
> db.user.remove({})

查询数据

db.collection.find([query],[fields])

注:
query :可选,使用查询操作符指定查询条件
fields :可选,使用投影操作符指定返回的键。查询时返回文档中所有键值, 只需省略该参数即可(默认省略)。

在查询时,通过query指定查询条件:

操作       说明           范例             RDBMS中的类似语句

等于     {<key>:<value>}      db.col.find({"by":"程序员"}).pretty()  where by = '程序员'
小于     {<key>:{$lt:<value>}}    db.col.find({"likes":{$lt:50}}).pretty()    where likes < 50
小于或等于  {<key>:{$lte:<value>}}     db.col.find({"likes":{$lte:50}}).pretty()  where likes <= 50
大于     {<key>:{$gt:<value>}}   db.col.find({"likes":{$gt:50}}).pretty()   where likes > 50
大于或等于  {<key>:{$gte:<value>}}   db.col.find({"likes":{$gte:50}}).pretty()    where likes >= 50
不等于    {<key>:{$ne:<value>}}    db.col.find({"likes":{$ne:50}}).pretty()     where likes != 50

#插入测试数据
db.user.insert({id:1,username:'zhangsan',age:20})
db.user.insert({id:2,username:'lisi',age:21})
db.user.insert({id:3,username:'wangwu',age:22})
db.user.insert({id:4,username:'zhaoliu',age:22})

db.user.find()  #查询全部数据
db.user.find({},{id:1,username:1})  #只查询id与username字段
db.user.find().count()  #查询数据条数
db.user.find({id:1}) #查询id为1的数据
db.user.find({age:{$lte:21}}) #查询小于等于21的数据
db.user.find({$or:[{id:1},{id:2}]}) #查询id=1 or id=2

#分页查询:Skip()跳过几条,limit()查询条数
db.user.find().limit(2).skip(1)  #跳过1条数据,查询2条数据
db.user.find().sort({id:-1}) #按照id倒序排序,-1为倒序,1为正序

索引

为了提高查询效率,MongoDB中也支持索引。

#查看索引
db.user.getIndexes()
#创建索引
#db.user.createIndex({'age':1})

注:1 :升序索引  -1 :降序索引

Springboot整合MongoDB

Spring-data对MongoDB做了支持,使用spring-data-mongodb可以简化MongoDB的操作,封装了底层的mongodb-driver。
地址:https://spring.io/projects/spring-data-mongodb
使用Spring-Data-MongoDB很简单,只需要如下几步即可:
  导入起步依赖
  编写配置信息
  编写实体类(配置注解 @Document,@Id)
  操作mongodb
    注入MongoTemplate对象,完成CRUD操作
    编写Repository接口,注入接口完成基本Crud操作

环境搭建

第一步,导入依赖:

 1 <parent>
 2     <groupId>org.springframework.boot</groupId>
 3     <artifactId>spring-boot-starter-parent</artifactId>
 4     <version>2.3.9.RELEASE</version>
 5 </parent>
 6 <dependencies>
 7     <dependency>
 8          <groupId>org.springframework.boot</groupId>
 9          <artifactId>spring-boot-starter-data-mongodb</artifactId>
10     </dependency>
11     <dependency>
12         <groupId>org.springframework.boot</groupId>
13         <artifactId>spring-boot-starter-test</artifactId>
14         <scope>test</scope>
15     </dependency>
16 </dependencies>

第二步,编写application.yml配置文件:

1 spring:
2   data:
3     mongodb:
4       uri: mongodb://192.168.136.160:27017/test

第三步,编写启动类

1 @SpringBootApplication
2 public class MongoApplication {
3 
4     public static void main(String[] args) {
5         SpringApplication.run(MongoApplication.class, args);
6     }
7 }

完成基本操作

第一步,编写实体类

 1 @Data
 2 @Document(value="tb_person")
 3 public class Person {
 4     @Id
 5     private ObjectId id;
 6     @Field("myname")
 7     private String name;
 8     private int age;
 9     private String address;
10 }

第二步,通过MongoTemplate完成CRUD操作

 1 @RunWith(SpringRunner.class)
 2 @SpringBootTest(classes = MongoApplication.class)
 3 public class MongoTest {
 4     /**
 5      *    1、注入MongoTemplate对象
 6      *    2、调用对象方法完成数据的CRUD
 7      */
 8     @Autowired
 9     private MongoTemplate mongoTemplate;
10 
11     //保存
12     @Test
13     public void testSave() {
14         Person person = new Person();
15         person.setName("张三");
16         person.setAge(18);
17         person.setAddress("北京");
18         mongoTemplate.save(person);
19     }
20 
21     /**
22      * 查询所有
23      */
24     @Test
25     public void testFindAll() {
26         List<Person> list = mongoTemplate.findAll(Person.class);
27         for (Person person : list) {
28             System.out.println(person);
29         }
30     }
31 
32     /**
33      * 条件查询
34      */
35     @Test
36     public void testFind() {
37         //1、创建Criteria对象,并设置查询条件
38         Criteria criteria = Criteria.where("myname").is("张三")
39                 .and("age").is(18)
40                 ;//is 相当于sql语句中的=
41         //2、根据Criteria创建Query
42         Query query = new Query(criteria);
43         //3、查询
44         List<Person> list = mongoTemplate.find(query, Person.class);//Query对象,实体类对象字节码
45         for (Person person : list) {
46             System.out.println(person);
47         }
48     }
49 
50     /**
51      * 分页查询
52      */
53     @Test
54     public void testPage() {
55         int page = 1;
56         int size = 2;
57         //1、创建Criteria对象,并设置查询条件
58         Criteria criteria = Criteria.where("age").lt(50); //is 相当于sql语句中的=
59         //2、根据Criteria创建Query
60         Query queryLimit = new Query(criteria)
61                 .skip((page -1) * size) //从第几条开始查询
62                 .limit(size) //每页查询条数
63                 .with(Sort.by(Sort.Order.desc("age")));
64         //3、查询
65         List<Person> list = mongoTemplate.find(queryLimit, Person.class);
66         for (Person person : list) {
67             System.out.println(person);
68         }
69     }
70 
71 
72     /**
73      * 更新
74      */
75     @Test
76     public void testUpdate() {
77         //1、构建Query对象
78         Query query = Query.query(Criteria.where("id").is("61275c3980f68e67ab4fdf25"));
79         //2、设置需要更新的数据内容
80         Update update = new Update();
81         update.set("age", 10);
82         update.set("myname", "lisi");
83         //3、调用方法
84         mongoTemplate.updateFirst(query, update, Person.class);
85     }
86 
87     //删除
88     @Test
89     public void testDelete() {
90         //1、构建Query对象
91         Query query = Query.query(Criteria.where("id").is("5fe404c26a787e3b50d8d5ad"));
92         mongoTemplate.remove(query, Person.class);
93     }
94 }

 

posted @ 2023-08-03 20:35  溯鸣  阅读(28)  评论(0编辑  收藏  举报