PostMan請求方法GET/POST
MongoDB簡介
一、什麼是MongoDB
- MongoDB 是由C++語言編寫的,是一個基於分散式檔案儲存的開源資料庫系統。
- 在高負載的情況下,新增更多的節點,可以保證伺服器效能。
- MongoDB 旨在為WEB應用提供可擴充套件的高效能資料儲存解決方案。
- MongoDB 將資料儲存為一個文件,資料結構由鍵值(key=>value)對組成。MongoDB 文件類似於 JSON 物件。欄位值可以包含其他文件,陣列及文件陣列。
二、MongoDB特點
1、MongoDB 是一個面向文件儲存的資料庫,操作起來比較簡單和容易。
2、你可以在MongoDB記錄中設定任何屬性的索引 (如:FirstName="Sameer",Address="8 Gandhi Road")來實現更快的排序。
3、你可以通過本地或者網路建立資料映象,這使得MongoDB有更強的擴充套件性。
4、如果負載的增加(需要更多的儲存空間和更強的處理能力),它可以分佈在計算機網路中的其他節點上這就是所謂的分片。
5、Mongo支援豐富的查詢表示式。查詢指令使用JSON形式的標記,可輕易查詢文件中內嵌的物件及陣列。
6、MongoDb 使用update()命令可以實現替換完成的文件(資料)或者一些指定的資料欄位。
7、Mongodb中的Map/reduce主要是用來對資料進行批量處理和聚合操作。
8、Map和Reduce。Map函式呼叫emit(key,value)遍歷集合中所有的記錄,將key與value傳給Reduce函式進行處理。
9、Map函式和Reduce函式是使用Javascript編寫的,並可以通過db.runCommand或mapreduce命令來執行MapReduce操作。
10、GridFS是MongoDB中的一個內建功能,可以用於存放大量小檔案。
11、MongoDB允許在服務端執行指令碼,可以用Javascript編寫某個函式,直接在服務端執行,也可以把函式的定義儲存在服務端,下次直接呼叫即可。
12、MongoDB支援各種程式語言:RUBY,PYTHON,JAVA,C++,PHP,C#等多種語言。
13、MongoDB安裝簡單。
三、MongoDB安裝
1、拉取映象
docker pull mongo:latest
或者docker pull mongo:4.4.8
2、建立和啟動容器
(1)對data目錄授權
chmod 777 data
(2)建立和啟動容器
docker run -d --restart=always -p 27017:27017 --name mymongo -v /data/db:/data/db -d mongo
或者docker run -d --restart=always -p 27017:27017 --name mymongo -v /data/db:/data/db -d mongo:4.4.8
3、進入容器
docker exec -it mymongo /bin/bash
4、使用MongoDB客戶端進行操作
mongo
show dbs
四、MongoDB 概念解析
五、資料庫操作
- 一個mongodb中可以建立多個數據庫,常用操作如下:
(1)Help檢視命令提示
db.help();
(2)切換/建立資料庫
use test
:如果資料庫不存在,則建立資料庫,否則切換到指定資料庫
(3) 查詢所有資料庫
show dbs;
(4)刪除當前使用資料庫
db.dropDatabase();
(5)檢視當前使用的資料庫
db.getName();
(6)顯示當前db狀態
db.stats();
(7)當前db版本
db.version();
(8) 檢視當前db的連結機器地址
db.getMongo();
六、文件
- 文件是一組鍵值(key-value)對(即BSON)。MongoDB 的文件不需要設定相同的欄位,並且相同的欄位不需要相同的資料型別,這與關係型資料庫有很大的區別,也是 MongoDB 非常突出的特點。
需要注意的是:
1、文件中的鍵/值對是有序的。
2、文件中的值不僅可以是在雙引號裡面的字串,還可以是其他幾種資料型別(甚至可以是整個嵌入的文件)。
3、MongoDB區分型別和大小寫。
4、MongoDB的文件不能有重複的鍵。
5、文件的鍵是字串。除了少數例外情況,鍵可以使用任意UTF-8字元。
文件鍵命名規範:
1、鍵不能含有\0 (空字元)。這個字元用來表示鍵的結尾。
2、.和$有特別的意義,只有在特定環境下才能使用。
3、以下劃線"_"開頭的鍵是保留的(不是嚴格要求的)。
七、集合
集合就是 MongoDB 文件組,類似於 RDBMS (關係資料庫管理系統:Relational Database Management System)中的表格。
集合存在於資料庫中,集合沒有固定的結構,這意味著你在對集合可以插入不同格式和型別的資料,但通常情況下我們插入集合的資料都會有一定的關聯性。
常用命令:
1、 建立一個集合(table)db.createCollection( "collName");
2、 得到指定名稱的集合(table )db.getCollection("user");
八、MongoDB的資料型別
九、MongoDB適用場景
適用場景
1、網站資料:Mongo非常適合實時的插入,更新與查詢,並具備網站實時資料儲存所需的複製及高度伸縮性。
2、快取:由於效能很高,Mongo也適合作為資訊基礎設施的快取層。在系統重啟之後,由Mongo搭建的持久化快取層可以避免下層的資料來源過載。
3、大尺寸,低價值的資料:使用傳統的關係型資料庫儲存一些資料時可能會比較昂貴,在此之前,很多時候程式設計師往往會選擇傳統的檔案進行儲存。
4、高伸縮性的場景:Mongo非常適合由數十或數百臺伺服器組成的資料庫。Mongo的路線圖中已經包含對Map Reduce弓摩的內建支援。
5、用於物件及 JSON資料的儲存:Mongo的BSON資料格式非常適合文件化格式的儲存及查詢。
不適用場合
1、高度事務性系統:例如銀行系統。傳統的關係型資料庫目前還是更適用於需要大量原子性複雜事務的應用程式。
2、傳統的商業智慧應用:針對特定問題的BI資料庫會對產生高度優化的查詢方式。對於此類應用,資料倉庫可能是更合適的選擇。
十、MongoDB常用操作
- INSERT
db.User.save({name:'zhangsan',age:21,sex:true})
db.User.insert({name:'lisi',age:22,sex:false})
db.User.find({name:'lisi'})
- FIELDS
select name, age from User where age = 20
db.User.find({age:20}, {'name':1, 'age':1})
- SORT
在 MongoDB 中使用 sort() 方法對資料進行排序,sort() 方法可以通過引數指定排序的欄位,並使用 1 和 -1 來指定排序的方式,其中 1 為升序排列,而 -1 是用於降序排列。
select * from User order by age
db.User.find().sort({age:1})
- SUCE
在 MongoDB 中使用 limit()方法來讀取指定數量的資料,skip()方法來跳過指定數量的資料
select * from User skip 2 limit 3
db.User.find().skip(0).limit(3)
- IN
select * from User where age in (21, 26, 32)
db.User.find({age:{$in:[21,26,32]}})
- COUNT
select count(*) from User where age >20
db.User.find({age:{$gt:20}}).count()
- OR
select * from User where age = 20 or age = 30
db.User.find({$or:[{age:20}, {age:30}]})
- UPDATE
update User set age = 100, sex = 0 where name = 'lucy'
db.User.update({name:"lucy"}, {$set:{age:100, sex:0}})
-
Update()有幾個引數需要注意。
-
db.collection.update(criteria, objNew, upsert, mult)
criteria:需要更新的條件表示式
objNew:更新表示式
upsert:如FI標記錄不存在,是否插入新文件。
multi:是否更新多個文件。
- Remove
remove()用於刪除單個或全部文件,刪除後的文件無法恢復
- 移除對應id的行
db.User.remove(id)
- 移除所有
db.User.remove({})
- aggregate聚合
MongoDB中聚合(aggregate)主要用於處理資料(諸如統計平均值,求和等),並返回計算後的資料結果。有點類似sql語句中的 count(*)
插入測試資料
db.article.insert({
title: 'MongoDB Overview',
description: 'MongoDB is no sql database',
by_user: 'runoob.com',
url: 'http://www.runoob.com',
tags: ['mongodb', 'database', 'NoSQL'],
likes: 100
})
db.article.insert({
title: 'NoSQL Overview',
description: 'No sql database is very fast',
by_user: 'runoob.com',
url: 'http://www.runoob.com',
tags: ['mongodb', 'database', 'NoSQL'],
likes: 10
})
db.article.insert({
title: 'Neo4j Overview',
description: 'Neo4j is no sql database',
by_user: 'Neo4j',
url: 'http://www.neo4j.com',
tags: ['neo4j', 'database', 'NoSQL'],
likes: 750
})
通過以上集合計算每個作者所寫的文章數
select by_user, count(*) from article group by by_user
db.article.aggregate([{$group : {_id : "$by_user", num_tutorial : {$sum : 1}}}])
- 常見的聚合表示式
$sum
計算總和。
db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$sum : "$likes"}}}])
$avg
計算平均值
db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$avg : "$likes"}}}])
$min
獲取集合中所有文件對應值得最小值。
db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$min : "$likes"}}}])
$max
獲取集合中所有文件對應值得最大值。
db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$max : "$likes"}}}])
$push
在結果文件中插入值到一個數組中。
db.mycol.aggregate([{$group : {_id : "$by_user", url : {$push: "$url"}}}])
$addToSet
在結果文件中插入值到一個數組中,但不建立副本。
db.mycol.aggregate([{$group : {_id : "$by_user", url : {$addToSet : "$url"}}}])
$first
根據資源文件的排序獲取第一個文件資料。
db.mycol.aggregate([{$group : {_id : "$by_user", first_url : {$first : "$url"}}}])
$last
根據資源文件的排序獲取最後一個文件資料
db.mycol.aggregate([{$group : {_id : "$by_user", last_url : {$last : "$url"}}}])
- 索引
索引通常能夠極大的提高查詢的效率,如果沒有索引,MongoDB在讀取資料時必須掃描集合中的每個檔案並選取那些符合查詢條件的記錄。這種掃描全集合的查詢效率是非常低的,特別在處理大量的資料時,查詢可以要花費幾十秒甚至幾分鐘,這對網站的效能是非常致命的。索引是特殊的資料結構,索引儲存在一個易於遍歷讀取的資料集合中,索引是對資料庫表中一列或多列的值進行排序的一種結構。
db.User.createIndex({"name":1})
語法中 name值為你要建立的索引欄位,1 為指定按升序建立索引,如果你想按降序來建立索引指定為 -1 即可
十一、SpringBoot繼承MongoDB之MongoTemplate
MongoTemplate開發CRUD
1.建立一個SpringBoot專案
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>
<groupId>com.qbb</groupId>
<artifactId>springboot-mongodb</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springboot-mongodb</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<spring-boot.version>2.3.7.RELEASE</spring-boot.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.3.7.RELEASE</version>
<configuration>
<mainClass>com.qbb.mongodb.SpringbootMongodbApplication</mainClass>
</configuration>
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
3.寫yml配置檔案
# 應用名稱
spring:
application:
name: springboot-mongodb
# mongo連線資訊
data:
mongodb:
uri: mongodb://192.168.137.72:27017/test
4.主啟動類
package com.qbb.mongodb;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SpringbootMongodbApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootMongodbApplication.class, args);
}
}
5.業務Bean
- 建立一個User類
package com.qbb.mongodb.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
import java.time.LocalDateTime;
/**
* @author QiuQiu&LL (個人部落格:https://www.cnblogs.com/qbbit)
* @version 1.0
* @date 2022-04-18 21:15
* @Description:
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@Document("User")
public class User {
@Id
private String id;
private String name;
private Integer age;
private String email;
private LocalDateTime createDate;
}
6.測試
package com.qbb.mongodb.controller;
import com.mongodb.client.result.DeleteResult;
import com.mongodb.client.result.UpdateResult;
import com.qbb.mongodb.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
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 org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
/**
* @author QiuQiu&LL (個人部落格:https://www.cnblogs.com/qbbit)
* @version 1.0
* @date 2022-04-19 8:32
* @Description:
*/
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private MongoTemplate mongoTemplate;
/**
* 新增
*
* @return
*/
@GetMapping("/insert")
public String insertUser() {
User user = new User("1", "zs", 21, "[email protected]", LocalDateTime.now());
mongoTemplate.insert(user);
return "success";
}
@GetMapping("/save")
public String saveUser() {
// 使用save時,資料此ID資料已存在,則做修改,不存在做新增
// User user = new User("2", "王五", 25, "王五@qq.com", LocalDateTime.now());
// mongoTemplate.save(user);
List<User> list = new ArrayList<>();
for (int i = 3; i < 20; i++) {
User user = new User(i + "", "qiuqiu" + i, 18 + i, "qiuqiu" + i + "@qq.com", LocalDateTime.now());
list.add(user);
}
mongoTemplate.insertAll(list);
return "success";
}
/**
* 查詢所有
*
* @return
*/
@GetMapping("/findAll")
public List<User> findAll() {
return mongoTemplate.findAll(User.class);
}
/**
* 根據id查詢
*/
@GetMapping("/findById")
public void findById() {
User user = mongoTemplate.findById(7, User.class);
System.out.println("user = " + user);
}
//條件查詢
@GetMapping("findUser")
public void findUserList() {
Query query = new Query(Criteria
.where("name").is("tqiu")
.and("age").is(20));
List<User> userList = mongoTemplate.find(query, User.class);
System.out.println(userList);
}
//模糊查詢
@GetMapping("findLike")
public void findUsersLikeName() {
String name = "qiu";
String regex = String.format("%s%s%s", "^.*", name, ".*$");
Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
Query query = new Query(Criteria.where("name").regex(pattern));
List<User> userList = mongoTemplate.find(query, User.class);
System.out.println(userList);
}
//分頁查詢
@GetMapping("findPage")
public void findUsersPage() {
String name = "qiu";
int pageNo = 1;
int pageSize = 10;
Query query = new Query();
String regex = String.format("%s%s%s", "^.*", name, ".*$");
Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
query.addCriteria(Criteria.where("name").regex(pattern));
int totalCount = (int) mongoTemplate.count(query, User.class);
List<User> userList = mongoTemplate.find(query.skip((pageNo - 1) * pageSize).limit(pageSize), User.class);
Map<String, Object> pageMap = new HashMap<>();
pageMap.put("list", userList);
pageMap.put("totalCount", totalCount);
System.out.println(pageMap);
}
//修改
@GetMapping("update")
public void updateUser() {
User user = mongoTemplate.findById("5ffbfa2ac290f356edf9b5aa", User.class);
user.setName("tqiu_1");
user.setAge(25);
user.setEmail("[email protected]");
Query query = new Query(Criteria.where("_id").is(user.getId()));
Update update = new Update();
update.set("name", user.getName());
update.set("age", user.getAge());
update.set("email", user.getEmail());
UpdateResult result = mongoTemplate.upsert(query, update, User.class);
long count = result.getModifiedCount();
System.out.println(count);
}
//刪除操作
@GetMapping("delete")
public void delete() {
Query query =
new Query(Criteria.where("_id").is("5ffbfa2ac290f356edf9b5aa"));
DeleteResult result = mongoTemplate.remove(query, User.class);
long count = result.getDeletedCount();
System.out.println(count);
}
}
十二、SpringBoot整合MongoDB之MongoRepository開發CRUD
SpringData 方法定義規範
1、不是隨便宣告的,而需要符合一定的規範
2、 查詢方法以find | read | get開頭
3、 涉及條件查詢時,條件的屬性用條件關鍵字連線
4、 要注意的是:條件屬性首字母需要大寫
5、 支援屬性的級聯查詢,但若當前類有符合條件的屬性則優先使用,而不使用級聯屬性,若需要使用級聯屬性,則屬性之間使用_強制進行連線
定義一個介面繼承MongoRepository<實體型別,主鍵型別>
package com.qbb.mongodb.repository;
import com.qbb.mongodb.entity.User;
import org.springframework.data.mongodb.repository.MongoRepository;
/**
* @author QiuQiu&LL (個人部落格:https://www.cnblogs.com/qbbit)
* @version 1.0
* @date 2022-04-19 13:01
* @Description:
*/
public interface UserRepository extends MongoRepository<User, String> {
}
測試
package com.qbb.mongodb.controller;
import com.qbb.mongodb.entity.User;
import com.qbb.mongodb.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* @author QiuQiu&LL (個人部落格:https://www.cnblogs.com/qbbit)
* @version 1.0
* @date 2022-04-19 13:04
* @Description:
*/
@RestController
@RequestMapping("/user2")
public class UserController2 {
@Autowired
private UserRepository userRepository;
//新增
@GetMapping("create")
public void createUser() {
User user = new User();
user.setAge(20);
user.setName("張三");
user.setEmail("[email protected]");
User user1 = userRepository.save(user);
}
//查詢所有
@GetMapping("findAll")
public void findUser() {
List<User> userList = userRepository.findAll();
System.out.println(userList);
}
//id查詢
@GetMapping("findId")
public void getById() {
User user = userRepository.findById("60b8d57ed539ed5b124942de").get();
System.out.println(user);
}
//條件查詢
@GetMapping("findQuery")
public void findUserList() {
User user = new User();
user.setName("張三");
user.setAge(20);
Example<User> userExample = Example.of(user);
List<User> userList = userRepository.findAll(userExample);
System.out.println(userList);
}
//模糊查詢
@GetMapping("findLike")
public void findUsersLikeName() {
//建立匹配器,即如何使用查詢條件
ExampleMatcher matcher = ExampleMatcher.matching() //構建物件
.withStringMatcher(ExampleMatcher.StringMatcher.CONTAINING) //改變預設字串匹配方式:模糊查詢
.withIgnoreCase(true); //改變預設大小寫忽略方式:忽略大小寫
User user = new User();
user.setName("三");
Example<User> userExample = Example.of(user, matcher);
List<User> userList = userRepository.findAll(userExample);
System.out.println(userList);
}
//分頁查詢
@GetMapping("findPage")
public void findUsersPage() {
Sort sort = Sort.by(Sort.Direction.DESC, "age");
//0為第一頁
Pageable pageable = PageRequest.of(0, 10, sort);
//建立匹配器,即如何使用查詢條件
ExampleMatcher matcher = ExampleMatcher.matching() //構建物件
.withStringMatcher(ExampleMatcher.StringMatcher.CONTAINING) //改變預設字串匹配方式:模糊查詢
.withIgnoreCase(true); //改變預設大小寫忽略方式:忽略大小寫
User user = new User();
user.setName("三");
Example<User> userExample = Example.of(user, matcher);
//建立例項
Example<User> example = Example.of(user, matcher);
Page<User> pages = userRepository.findAll(example, pageable);
System.out.println(pages);
}
//修改
@GetMapping("update")
public void updateUser() {
User user = userRepository.findById("60b8d57ed539ed5b124942de").get();
user.setName("張三_1");
user.setAge(25);
user.setEmail("[email protected]");
User save = userRepository.save(user);
System.out.println(save);
}
//刪除
@GetMapping("delete")
public void delete() {
userRepository.deleteById("60b8d57ed539ed5b124942de");
}
}
自定義方法
@GetMapping("testMethod2")
public void testMethod2() {
List<User> users = userRepository.findByNameLike("張");
System.out.println(users);
}
@GetMapping("testMethod1")
public void testMethod1() {
List<User> users = userRepository.findByName("張三");
System.out.println(users);
}
@Repository
public interface UserRepository extends MongoRepository<User, String> {
List<User> findByName(String name);
List<User> findByNameLike(String name);
}