NoSQL(NoSQL = Not Only SQL),意即反SQL运动,指的是非关系型的数据库,是一项全新的数据库革命性运动,早期就有人提出,发展至2009年趋势越发高涨。NoSQL的拥护者们提倡运用非关系型的数据存储,相对于目前铺天盖地的关系型数据库运用,这一概念无疑是一种全新的思维的注入
MongoDB 是由C++语言编写的,是一个基于分布式文件存储的开源数据库系统。在高负载的情况下,添加更多的节点,可以保证服务器性能。MongoDB 旨在为WEB应用提供可扩展的高性能数据存储解决方案。MongoDB 将数据存储为一个文档,数据结构由键值(key=>value)对组成。MongoDB 文档类似于 JSON 对象。字段值可以包含其他文档,数组及文档数组
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安装简单。
1、网站数据:Mongo非常适合实时的插入,更新与查询,并具备网站实时数据存储所需的复制及高度伸缩性。
2、缓存:由于性能很高,Mongo也适合作为信息基础设施的缓存层。在系统重启之后,由M ongo搭建的持久化缓存层可以避免下层的数据源过载。
3、大尺寸,低价值的数据:使用传统的关系型数据库存储一些数据时可能会比较昂贵, 在此之前,很多时候程序员往往会选择传统的文件进行存储。
4、高伸缩性的场景:Mongo非常适合由数十或数百台服务器组成的数据库。Mongo的路线图中已经包含对Map Reduce弓摩的内置支持。
5、用于对象及 JSON数据的存储:Mongo的BSON数据格式非常适合文档化格式的存储 及查询。
1、高度事务性的系统:例如银行或会计系统。传统的关系型数据库目前还是更适用于需要大量原子性复杂事务的应用程序。
2、传统的商业智能应用:针对特定问题的BI数据库会对产生高度优化的查询方式。对于此类应用,数据仓库可能是更合适的选择。
MongoDB | 关系型数据库Mysql |
---|---|
数据库(databases) | 关系型数据库Mysql |
集合(collections) | 表(table) |
文档 (document) | 行(row) |
小结:
MongoDB的体系结构
docker pull mongo
docker run -di --name=tensquare_mongo -p 27017:27017 mongo
docker exec -it 593668d02238 /bin/bash
mongo
小结:
docker 安装,先拉取镜像,在创建容器
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〇;
use 数据库名
show dbs
>
> use xiaoguo //创建数据 名为 小果
switched to db xiaoguo
>
>
>
>
>
> // 创建数据集合名为spit 添加字段({name:'xiaoguo',age:NumberInt('18'),sex:'男'})
> db.spit.insert({
name:'xiaoguo',age:NumberInt('18'),sex:'男'})
WriteResult({
"nInserted" : 1 })
>
>
>
>
> //查询所有的文档
> db.spit.find()
{
"_id" : ObjectId("60fa3b12f217797a07c7d7f2"), "name" : "xiaoguo", "age" : 18, "sex" : "男" }
>
小结:
>
> //查询数据库 下有几个集合
> show collections 删除
spit
>
修改文档格式
1.db.集合名称.update({条件},{跟新逻辑});
上面语法,会更新指定字段,但是其他字段没了,希望其他字段不影响的话,执行一下语句
2.db.集合名称.update({条件},{$set:{跟新逻辑}})
更新文档
> db.spit.find()
{
"_id" : ObjectId("60fa3b12f217797a07c7d7f2"), "name" : "xiaoguo", "age" : 18, "sex" : "男" }
>
> //第一种方式修改
> db.spit.update({
_id: ObjectId("60fa3b12f217797a07c7d7f2")},{
name:'xiaoyaya'})
WriteResult({
"nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.spit.find()
// 发现就剩一个name属性了,
{
"_id" : ObjectId("60fa3b12f217797a07c7d7f2"), "name" : "xiaoyaya" }
>
//添加数据
> db.spit.insert({
_id:'2',name:'xjggb',age:NumberInt('16'),sex:'男'})
WriteResult({
"nInserted" : 1 })
//第二种方式修改
> db.spit.update({
_id:'2'},{
$set:{
age: NumberInt('6')}})
WriteResult({
"nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.spit.find()
{
"_id" : ObjectId("60fa3b12f217797a07c7d7f2"), "name" : "xiaoyaya" }
{
"_id" : "1", "name" : "xjggb", "age" : {
"code" : "function NumberInt() {\n [native code]\n}" }, "sex" : "男" }
{
"_id" : "2", "name" : "xjggb", "age" : 6, "sex" : "男" }
删除文档
格式
db.集合名称.remove({条件}) 推荐条件
db.集合名称.remove({}) 删库跑路
//查询全部数据
> db.spit.find()
{
"_id" : "1", "name" : "xjggb", "age" : {
"code" : "function NumberInt() {\n [native code]\n}" }, "sex" : "男" }
{
"_id" : "2", "name" : "xjggb", "age" : 6, "sex" : "男" }
//根据id删除
> db.spit.remove({
_id:'1'})
WriteResult({
"nRemoved" : 1 })
> db.spit.find()
{
"_id" : "2", "name" : "xjggb", "age" : 6, "sex" : "男" }
//不带条件删除全部数据(删库跑路)
> db.spit.remove({
})
WriteResult({
"nRemoved" : 1 })
> db.spit.find()
>
小结:
修改文档时,只修改某个字段,不影响其他字段?
需要用到$set
模拟数据
db.spit.insert({
_id:"1",content:"我还是没有想明白到底为啥出错",userid:"1012",nickname:"小明",visits:NumberInt(2020)})
db.spit.insert({
_id:"2",content:"加班到半夜",userid:"1013",nickname:"凯撒",visits:NumberInt(1023)})
db.spit.insert({
_id:"3",content:"手机流量超了咋办?",userid:"1013",nickname:"凯撒",visits:NumberInt(111)})
db.spit.insert({
_id:"4",content:"坚持就是胜利",userid:"1014",nickname:"诺诺",visits:NumberInt(1223)})
明确文档统计命令
db.集合名称.count() //统计所有
db.集合名称.count({条件}) //根据条件统计
//统计所有
> db.spit.count()
4
模糊查询
db.集合名称.find( {key:/value/} )
数据类型 | 描述 |
---|---|
Regular expression | 正则表达式类型。用于存储正则表达式。 |
Code | 代码类型。用于在文档中存储 JavaScript 代码。 |
Binary Data | 二进制数据。用于存储二进制数据。 |
Object ID | 对象 ID。用于创建文档的 ID。 |
Date | 日期时间。用 UNIX 时间格式来存储当前日期或时间。你可以指定自己的日期时间:创建 Date 对象,传入年月日信息。 |
Symbol | 符号。该数据类型基本上等同于字符串类型,但不同的是,它一般用于采用特殊符号类型的语言。 |
String | 字符串。存储数据常用的数据类型。在 MongoDB 中,UTF-8 编码的字符串才是合法的。 |
Integer | 整型数值。用于存储数值。根据你所采用的服务器,可分为 32 位或 64 位。 |
Boolean | 布尔值。用于存储布尔值(真/假)。 |
Double | 双精度浮点值。用于存储浮点值。 |
Min/Max keys | 将一个值与 BSON(二进制的 JSON)元素的最低值和最高值相对比。 |
Arrays | 用于将数组或列表或多个值存储为一个键。 |
Timestamp | 时间戳。记录文档修改或添加的具体时间。 |
Object | 用于内嵌文档。 |
Null | 用于创建空值。 |
spring-data-mongodb提供了MongoTemplate与MongoRepository两种方式访问mongodb,MongoRepository操作简单,MongoTemplate操作灵活,我们在项目中可以灵活适用这两种方式操作mongodb,MongoRepository的缺点是不够灵活,MongoTemplate正好可以弥补不足。
使用 Spring Initializr 快速初始化一个 Spring Boot 工程
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-data-mongodbartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
<scope>testscope>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
dependency>
<dependency>
<groupId>joda-timegroupId>
<artifactId>joda-timeartifactId>
<version>2.10.1version>
dependency>
dependencies>
spring.data.mongodb.uri=mongodb://192.168.93.110:27017/test
package com.example.demo.entity;
import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.index.Indexed;
import org.springframework.data.mongodb.core.mapping.Document;
@Data
@Document("User")
public class User {
@Id
private String id;
private String name;
private Integer age;
private String email;
private String createDate;
}
常用方法
mongoTemplate.findAll(User.class): 查询User文档的全部数据
mongoTemplate.findById(, User.class): 查询User文档id为id的数据
mongoTemplate.find(query, User.class);: 根据query内的查询条件查询
mongoTemplate.upsert(query, update, User.class): 修改
mongoTemplate.remove(query, User.class): 删除
mongoTemplate.insert(User): 新增
Query对象
1、创建一个query对象(用来封装所有条件对象),再创建一个criteria对象(用来构建条件)
2、 精准条件:criteria.and(“key”).is(“条件”)
模糊条件:criteria.and(“key”).regex(“条件”)
3、封装条件:query.addCriteria(criteria)
4、大于(创建新的criteria):Criteria gt = Criteria.where(“key”).gt(“条件”)
小于(创建新的criteria):Criteria lt = Criteria.where(“key”).lt(“条件”)
5、Query.addCriteria(new Criteria().andOperator(gt,lt));
6、一个query中只能有一个andOperator()。其参数也可以是Criteria数组。
7、排序 :query.with(new Sort(Sort.Direction.ASC, “age”). and(new Sort(Sort.Direction.DESC, “date”)))
package com.example.demo;
import com.example.demo.entity.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.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.List;
import java.util.UUID;
import java.util.regex.Pattern;
@SpringBootTest
class DemoApplicationTests {
@Autowired
private MongoTemplate mongoTemplate;
/*
* 修改数据
* */
@Test
public void show5(){
User byId = mongoTemplate.findById("618bf3e767faef7aca361b64", User.class);
byId.setAge(99);
byId.setName("来了老弟");
Query query = new Query(Criteria.where("_id").is(byId.getId()));
Update update = new Update();
update.set("name",byId.getName());
update.set("email",byId.getEmail());
update.set("age",byId.getAge());
UpdateResult upsert = mongoTemplate.upsert(query, update, User.class);
long modifiedCount = upsert.getModifiedCount();
}
/*
* 模糊查询
* */
@Test
public void show4(){
String name = "est";
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);
}
/*
* 条件查询
* */
@Test
public void show3(){
/*
* 构建条件
* */
Query query = new Query(
Criteria.where("name").is("test").and("age").is(20)
);
List<User> users = mongoTemplate.find(query, User.class);
users.forEach(o-> System.out.println("o = " + o));
}
/*
* 根据id查询
* */
@Test
public void show2(){
User byId = mongoTemplate.findById("618bf3e767faef7aca361b64", User.class);
System.out.println("byId = " + byId);
}
/*
* 查询全部数据
* */
@Test
public void show1(){
List<User> all = mongoTemplate.findAll(User.class);
all.forEach(o-> System.out.println("o = " + o));
}
//添加数据
@Test
void contextLoads() {
User user = new User();
user.setId(UUID.randomUUID().toString());
user.setAge(20);
user.setName("test");
user.setEmail("[email protected]");
User insert = mongoTemplate.insert(user);
System.out.println("insert = " + insert);
}
/*
* 删除操作
* */
@Test
public void show6(){
Query query = new Query(Criteria.where("_id").is("618bf3e767faef7aca361b64"));
long deletedCount = mongoTemplate.remove(query, User.class).getDeletedCount();
System.out.println(deletedCount);
}
}
Spring Data提供了对mongodb数据访问的支持,我们只需要继承MongoRepository类,按照Spring Data规范就可以了
1、不是随便声明的,而需要符合一定的规范
2、 查询方法以find | read | get开头
3、 涉及条件查询时,条件的属性用条件关键字连接
4、 要注意的是:条件属性首字母需要大写
5、 支持属性的级联查询,但若当前类有符合条件的属性则优先使用,而不使用级联属性,若需要使用级联属性,则属性之间使用_强制进行连接
package com.example.demo.repository;
import com.example.demo.entity.User;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface UserRepository extends MongoRepository<User,String> {
}
package com.example.demo;
import com.example.demo.entity.User;
import com.example.demo.repository.UserRepository;
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.List;
import java.util.Optional;
import java.util.UUID;
@SpringBootTest
public class Demo01 {
@Autowired
private UserRepository userRepository;
/*
* 修改
* */
/*
* 条件查询
* */
@Test
public void show4(){
User user = new User();
user.setName("test");
user.setAge(20);
Example<User> of = Example.of(user);
List<User> all = userRepository.findAll(of);
all.forEach(o-> System.out.println("o = " + o));
}
/*
* 根据id查询
* */
@Test
public void show3(){
User user = userRepository.findById("5ce8fcc9-8500-48ec-b0fe-7be9eea4926d").get();
System.out.println(user);
}
/*
* 查询所有
* */
@Test
public void show2(){
List<User> all = userRepository.findAll();
all.forEach(o-> System.out.println("o = " + o));
}
/*
* 添加数据
* */
@Test
public void show(){
User user = new User();
user.setId(UUID.randomUUID().toString());
user.setAge(60);
user.setName("吾乃行健乖乖霸");
user.setEmail("[email protected]");
User save = userRepository.save(user);
System.out.println("save = " + save);
}
/*
* 模糊查询
* */
@Test
public void show6(){
//创建匹配器,
ExampleMatcher matching = ExampleMatcher.matching()
.withStringMatcher(ExampleMatcher.StringMatcher.CONTAINING)
.withIgnoreCase(true); //忽列大小写
User user = new User();
user.setName("行健");
Example<User> of = Example.of(user, matching);
List<User> all = userRepository.findAll(of);
all.forEach(o-> System.out.println("o = " + o));
}
/*
* 分页查询
* */
@Test
public void show7(){
//排序
Sort age = Sort.by(Sort.Direction.DESC, "age");
//分页
PageRequest pageRequest = PageRequest.of(0, 3, age);
//创建模糊查询条件
ExampleMatcher exampleMatcher = ExampleMatcher.matching()
.withStringMatcher(ExampleMatcher.StringMatcher.CONTAINING)//改变默认字符串匹配方式,模糊查询
.withIgnoreCase(true);//改变默认大小写忽略方式:忽略大小写
User user = new User();
user.setName("行健");
//创建实例
Example<User> example = Example.of(user, exampleMatcher);
Page<User> all = userRepository.findAll(example, pageRequest);
all.forEach(o-> System.out.println("o = " + o));
}
}
了解mongobd的使用
懂得mongodb的安装
了解mongodb的类型
懂得SpringBoot集成mongodb