【SpringBoot高级篇】SpringBoot集成MongDB数据库
【SpringBoot高级篇】SpringBoot集成MongDB数据库
- MongoDB是什么 ?
- 主要特点
- MongoDB管理 工具
- MongoDB 基本概念
- 数据库
- 文档(Document)
- 集合
- 合法的集合名
- capped collections
- 元数据
- MongoDB 数据类型
- ObjectId
- 字符串
- 时间戳
- 日期
- MongoDB基本命令
- MongoDB 创建数据库
- 语法
- 实例
- MongoDB 删除数据库
- 语法
- 实例
- 删除集合
- MongoDB 创建集合
- 语法
- 实例
- MongoDB 删除集合
- 语法
- 实例
- MongoDB 插入文档
- 语法
- 实例
- MongoDB 更新文档
- update() 方法
- 语法
- 实例
- save() 方法
- 语法
- 实例
- MongoDB 删除文档
- 语法
- 实例
- 注意
- MongoDB 查询文档
- 语法
- MongoDB 与 RDBMS Where 语句比较
- MongoDB AND 条件
- MongoDB OR 条件
- 实例
- AND 和 OR 联合使用
- docker 部署 mongodb
- 拉取镜像
- docker 安装 mongodb
- 进入容器.
- `mongodb`的使用
- 用户的创建
- 创建用户
- 数据库的建立
- mongo 是否正常启动的校验
- 远程连接的开启
- 基于MongoTemplate 开发CRUD
- 1、引入springboot mongo依赖
- 2、mongo的IP和端口
- 3、使用mongoTemplate
- User
- 常用方法
- 测试
- 测试
- 基于MongoRepository开发CRUD
- 添加Repository类
- 测试
- 多数据源 MongoDB 的使用
- pom
- yml
- MongoConfig
- Person
- 测试
MongoDB是什么 ?
- MongoDB 是由C++语言编写的,是一个基于分布式文件存储的开源数据库系统。
- 在高负载的情况下,添加更多的节点,可以保证服务器性能。
- MongoDB 旨在为WEB应用提供可扩展的高性能数据存储解决方案。
- MongoDB 将数据存储为一个文档,数据结构由键值(
key=>value
)对组成。MongoDB
文档类似于 JSON 对象。字段值可以包含其他文档,数组及文档数组。
{user: "admin", --->key=>valuepwd: "123456", --->key=>valueroles: [ { role: "userAdminAnyDatabase", db: "admin" } ]}
主要特点
- MongoDB 是一个面向文档存储的数据库,操作起来比较简单和容易。
- 你可以在MongoDB记录中设置任何属性的索引 (如:FirstName=“Sameer”,Address=“8 Gandhi Road”)来实现更快的排序。
- 你可以通过本地或者网络创建数据镜像,这使得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++,PHP,C#等多种语言。
- MongoDB安装简单。
MongoDB管理 工具
- Fang of Mongo – 网页式,由Django和jQuery所构成。
- Futon4Mongo – 一个CouchDB Futon web的mongodb山寨版。
- Mongo3 – Ruby写成。
- MongoHub – 适用于OSX的应用程序。
- Opricot – 一个基于浏览器的MongoDB控制台, 由PHP撰写而成。
- Database Master — Windows的mongodb管理工具
- RockMongo — 最好的PHP语言的MongoDB管理工具,轻量级, 支持多国语言.
MongoDB 基本概念
在mongodb中基本的概念是文档、集合、数据库
SQL术语/概念 | MongoDB术语/概念 | 解释/说明 |
---|---|---|
database | database | 数据库 |
table | collection | 数据库表/集合 |
row | document | 数据记录行/文档 |
column | field | 数据字段/域 |
index | index | 索引 |
table joins | 表连接,MongoDB不支持 | |
primary key | primary key | 主键,MongoDB自动将_id字段设置为主键 |
通过下图实例,我们也可以更直观的了解Mongo中的一些概念:
数据库
一个mongodb中可以建立多个数据库。MongoDB的默认数据库为"db",该数据库存储在data目录中。MongoDB的单个实例可以容纳多个独立的数据库,每一个都有自己的集合和权限,不同的数据库也放置在不同的文件中。
> show dbs # 命令可以显示所有数据的列表。
admin 0.000GB
config 0.000GB
demo 0.000GB
local 0.000GB
> db # 显示当前数据库对象或集合。
test
> use demo # 连接到一个指定的数据库。
switched to db demo
有一些数据库名是保留的,可以直接访问这些有特殊作用的数据库。
- admin: 从权限的角度来看,这是"root"数据库。要是将一个用户添加到这个数据库,这个用户自动继承所有数据库的权限。一些特定的服务器端命令也只能从这个数据库运行,比如列出所有的数据库或者关闭服务器。
- local: 这个数据永远不会被复制,可以用来存储限于本地单台服务器的任意集合
- config: 当Mongo用于分片设置时,config数据库在内部使用,用于保存分片的相关信息。
文档(Document)
文档是一组键值(key-value
)对(即 BSON
)。MongoDB 的文档不需要设置相同的字段,并且相同的字段不需要相同的数据类型,这与关系型数据库有很大的区别,也是 MongoDB 非常突出的特点。
{"site":"www.zysheep.cn", "name":"三月三"}
下表列出了 RDBMS 与 MongoDB 对应的术语:
RDBMS | MongoDB |
---|---|
数据库 | 数据库 |
表格 | 集合 |
行 | 文档 |
列 | 字段 |
表联合 | 嵌入文档 |
主键 | 主键 (MongoDB 提供了 key 为 _id ) |
需要注意的是:
- 文档中的键/值对是有序的。
- 文档中的值不仅可以是在双引号里面的字符串,还可以是其他几种数据类型(甚至可以是整个嵌入的文档)。
- MongoDB区分类型和大小写。
- MongoDB的文档不能有重复的键。
- 文档的键是字符串。除了少数例外情况,键可以使用任意UTF-8字符。
文档键命名规范:
- 键不能含有\0 (空字符)。这个字符用来表示键的结尾。
- .和$有特别的意义,只有在特定环境下才能使用。
- 以下划线"_"开头的键是保留的(不是严格要求的)。
集合
集合就是 MongoDB 文档组,类似于 RDBMS (关系数据库管理系统:Relational Database Management System)中的表格。集合存在于数据库中,集合没有固定的结构,这意味着你在对集合可以插入不同格式和类型的数据,但通常情况下我们插入集合的数据都会有一定的关联性。
比如,我们可以将以下不同数据结构的文档插入到集合中:
{"site":"www.baidu.com"}
{"site":"www.zysheep.cn","name":"三月三"}
{"site":"www.zysheep.cn","name":"三月三热爱生活","num":5}
合法的集合名
- 集合名不能是空字符串""。
- 集合名不能含有\0字符(空字符),这个字符表示集合名的结尾。
- 集合名不能以"system."开头,这是为系统集合保留的前缀。
- 用户创建的集合名字不能含有保留字符。有些驱动程序的确支持在集合名里面包含,这是因为某些系统生成的集合中包含该字符。除非你要访问这种系统创建的集合,否则千万不要在名字里出现$。
如下实例:
db.col.findOne()
capped collections
Capped collections 就是固定大小的collection。它有很高的性能以及队列过期的特性(过期按照插入的顺序). 有点和 “RRD” 概念类似。Capped collections 是高性能自动的维护对象的插入顺序。它非常适合类似记录日志的功能和标准的 collection 不同,你必须要显式的创建一个capped collection,指定一个 collection 的大小,单位是字节。collection 的数据存储空间值提前分配的。
db.createCollection("mycoll", {capped:true, size:100000})
- 在 capped collection 中,你能添加新的对象。
- 能进行更新,然而,对象不会增加存储空间。如果增加,更新就会失败 。
- 使用 Capped Collection 不能删除一个文档,可以使用 drop() 方法删除 collection 所有的行。
- 删除之后,你必须显式的重新创建这个 collection。
- 在32bit机器中,capped collection 最大存储为 1e9( 1X109)个字节。
元数据
数据库的信息是存储在集合中。它们使用了系统的命名空间:
dbname.system.*
在MongoDB数据库中名字空间 .system.* 是包含多种系统信息的特殊集合(Collection),如下:\
集合命名空间 | 描述 |
---|---|
dbname.system.namespaces | 列出所有名字空间。 |
dbname.system.indexes | 列出所有索引。 |
dbname.system.profile | 包含数据库概要(profile)信息。 |
dbname.system.users | 列出所有可访问数据库的用户。 |
dbname.local.sources | 包含复制对端(slave)的服务器信息和状态。 |
MongoDB 数据类型
数据类型 | 描述 |
---|---|
String | 字符串。存储数据常用的数据类型。在 MongoDB 中,UTF-8 编码的字符串才是合法的。 |
Integer | 整型数值。用于存储数值。根据你所采用的服务器,可分为 32 位或 64 位。 |
Boolean | 布尔值。用于存储布尔值(真/假)。 |
Double | 双精度浮点值。用于存储浮点值。 |
Min/Max keys | 将一个值与 BSON(二进制的 JSON)元素的最低值和最高值相对比。 |
Array | 用于将数组或列表或多个值存储为一个键。 |
Timestamp | 时间戳。记录文档修改或添加的具体时间。 |
Object | 用于内嵌文档。 |
Null | 用于创建空值。 |
Symbol | 符号。该数据类型基本上等同于字符串类型,但不同的是,它一般用于采用特殊符号类型的语言。 |
Date | 日期时间。用 UNIX 时间格式来存储当前日期或时间。你可以指定自己的日期时间:创建 Date 对象,传入年月日信息。 |
Object ID | 对象 ID。用于创建文档的 ID。 |
Binary Data | 二进制数据。用于存储二进制数据。 |
Code | 代码类型。用于在文档中存储 JavaScript 代码。 |
Regular expression | 正则表达式类型。用于存储正则表达式。 |
ObjectId
ObjectId 类似唯一主键,可以很快的去生成和排序,包含 12 bytes,含义是:
- 前 4 个字节表示创建 unix 时间戳,格林尼治时间 UTC 时间,比北京时间晚了 8 个小时
- 接下来的 3 个字节是机器标识码
- 紧接的两个字节由进程 id 组成 PID
- 最后三个字节是随机数
MongoDB 中存储的文档必须有一个 _id 键。这个键的值可以是任何类型的,默认是个 ObjectId 对象
由于 ObjectId 中保存了创建的时间戳,所以你不需要为你的文档保存时间戳字段,你可以通过 getTimestamp 函数来获取文档的创建时间:
> var newObject = ObjectId()
> newObject.getTimestamp()
ISODate("2020-06-02T00:41:51Z")
ObjectId 转为字符串
> newObject.str
5ed5a04fb5ebb889810105cf
字符串
BSON 字符串都是 UTF-8 编码。
时间戳
BSON 有一个特殊的时间戳类型用于 MongoDB 内部使用,与普通的 日期 类型不相关。 时间戳值是一个 64 位的值。其中:
- 前32位是一个 time_t 值(与Unix新纪元相差的秒数)
- 后32位是在某秒中操作的一个递增的
序数
在单个 mongod 实例中,时间戳值通常是唯一的。在复制集中, oplog 有一个 ts 字段。这个字段中的值使用BSON时间戳表示了操作时间。
BSON 时间戳类型主要用于 MongoDB 内部使用。在大多数情况下的应用开发中,你可以使用 BSON 日期类型。
日期
表示当前距离 Unix新纪元(1970年1月1日)的毫秒数。日期类型是有符号的, 负数表示 1970 年之前的日期。
> var mydate1 = new Date()
> mydate1
ISODate("2020-06-02T00:43:59.056Z")
> typeof mydate1
object
这样创建的时间是日期类型,可以使用 JS 中的 Date 类型的方法。
返回一个时间类型的字符串:
> var mydate1str = mydate1.toString()
> mydate1str
Tue Jun 02 2020 00:43:59 GMT+0000 (UTC)
> typeof mydate1str
string
或者
> Date()
Tue Jun 02 2020 00:45:23 GMT+0000 (UTC)
MongoDB基本命令
MongoDB 创建数据库
语法
use DATABASE_NAME
如果数据库不存在,则创建数据库,否则切换到指定数据库。
实例
> use zysheep # 创建数据库zysheep
switched to db zysheep
> show dbs # 查看所有数据库
admin 0.000GB
config 0.000GB
demo 0.000GB
local 0.000GB
> db.zysheep.insert({"sate":"zysheep"})
# 创建的数据库 zysheep 并不在数据库的列表中, 要显示它,我们需要向 zysheep 数据库插入一些数据。
WriteResult({ "nInserted" : 1 })
> show dbs
admin 0.000GB
config 0.000GB
demo 0.000GB
local 0.000GB
zysheep 0.000GB
> db # 查看当前所在数据库
zysheep
MongoDB 中默认的数据库为 test
,如果你没有创建新的数据库,集合将存放在 test 数据库中。
注意: 在 MongoDB 中,集合只有在内容插入后才会创建! 就是说,创建集合(数据表)后要再插入一个文档(记录),集合才会真正创建
MongoDB 删除数据库
语法
db.dropDatabase()
删除当前数据库,默认为 test
,你可以使用 db
命令查看当前数据库名。
实例
以下实例我们删除了数据库 zysheep。
> show dbs # 查看所有数据库
admin 0.000GB
config 0.000GB
demo 0.000GB
local 0.000GB
zysheep 0.000GB
> db # 查看当前数据库
zysheep
> db.dropDatabase() # 删除当前数据库
{ "dropped" : "zysheep", "ok" : 1 }
> show dbs # 查看是否删除
admin 0.000GB
config 0.000GB
demo 0.000GB
local 0.000GB
删除集合
> show dbs
admin 0.000GB
config 0.000GB
demo 0.000GB
local 0.000GB
> use zysheep
switched to db zysheep
> db.createCollection("zysheep") # 先创建集合,类似数据库中的表
{ "ok" : 1 }
> show tables # show collections 命令会更加准确点
zysheep
> db.zysheep.drop()
true
> show tables
MongoDB 创建集合
语法
db.createCollection(name, options)
- name: 要创建的集合名称
- options: 可选参数, 指定有关内存大小及索引的选项
options 可以是如下参数:
字段 | 类型 | 描述 |
---|---|---|
capped | 布尔 | (可选)如果为 true,则创建固定集合。固定集合是指有着固定大小的集合,当达到最大值时,它会自动覆盖最早的文档。 当该值为 true 时,必须指定 size 参数。 |
autoIndexId | 布尔 | (可选)如为 true,自动在 _id 字段创建索引。默认为 false。 |
size | 数值 | (可选)为固定集合指定一个最大值,以千字节计(KB)。 如果 capped 为 true,也需要指定该字段。 |
max | 数值 | (可选)指定固定集合中包含文档的最大数量。 |
在插入文档时,MongoDB 首先检查固定集合的 size 字段,然后检查 max 字段。
实例
> use demo #创建 demo 数据库
switched to db demo
> db.createCollection("demo") # 创建 demo 集合
{ "ok" : 1 }
> show collections # 查看已有集合
demo
info
> show tables # 查看已有集合
demo
info
> db.createCollection("mycol", { capped : true, autoIndexId : true, size :
... 6142800, max : 10000 } ) # 创建固定集合 mycol
{"note" : "the autoIndexId option is deprecated and will be removed in a future release","ok" : 1
}
> show tables # 查看已有集合
demo
info
mycol
> db.myclo2.insert({"name":"三月三"})
# 在 MongoDB 中,你不需要创建集合。当你插入一些文档时,MongoDB 会自动创建集合。
WriteResult({ "nInserted" : 1 })
> show tables
demo
info
myclo2
mycol
MongoDB 删除集合
语法
db.collection.drop()
如果成功删除选定集合,则 drop() 方法返回 true,否则返回 false。
实例
在数据库mydb
中,我们可以先通过 show collections
命令查看已存在的集合:
> use demo # 使用demo数据库
switched to db demo
> show tables # 查看当前数据库所有集合
demo
info
myclo2
mycol
> db.demo.drop() # 删除demo集合
true
> show tables;
info
myclo2
mycol
>
MongoDB 插入文档
文档的数据结构和 JSON
基本一样。所有存储在集合中的数据都是 BSON
格式。BSON
是一种类似 JSON 的二进制形式的存储格式,是 Binary JSON
的简称。
语法
MongoDB 使用 insert() 或 save() 方法向集合中插入文档,语法如下:
db.COLLECTION_NAME.insert(document)
或
db.COLLECTION_NAME.save(document)
- save():如果 _id 主键存在则更新数据,如果不存在就插入数据。该方法新版本中已废弃,可以使用 db.collection.insertOne() 或 db.collection.replaceOne() 来代替。
- insert(): 若插入的数据主键已经存在,则会抛 org.springframework.dao.DuplicateKeyException 异常,提示主键重复,不保存当前数据
3.2 版本之后新增了 db.collection.insertOne() 和 db.collection.insertMany()。
db.collection.insertOne() 用于向集合插入一个新文档,语法格式如下:
# 语法
db.collection.insertOne(<document>,{writeConcern: <document>}
)
# 实例
> var document = db.collection.insertOne({"a": 3})
> document
{"acknowledged" : true,"insertedId" : ObjectId("5ed5a93256fa4269b4e255ff")
}
db.collection.insertMany() 用于向集合插入一个多个文档,语法格式如下:
# 语法
db.collection.insertMany([ <document 1> , <document 2>, ... ],{writeConcern: <document>,ordered: <boolean>}
)
# 实例
> var res = db.collection.insertMany([{"b": 3}, {'c': 4}])
> res
{"acknowledged" : true,"insertedIds" : [ObjectId("5ed5a93f56fa4269b4e25600"),ObjectId("5ed5a93f56fa4269b4e25601")]
}
- document:要写入的文档。
- writeConcern:写入策略,默认为 1,即要求确认写操作,0 是不要求。
- ordered:指定是否按顺序写入,默认 true,按顺序写入。
实例
以下文档可以存储在 MongoDB 的 demo数据库 的 col 集合中:
>db.col.insert({title: 'MongoDB 教程', description: 'MongoDB 是一个 Nosql 数据库',by: '菜鸟教程',url: 'http://www.runoob.com',tags: ['mongodb', 'database', 'NoSQL'],likes: 100
})
>WriteResult({ "nInserted" : 1 })
以上实例中 col 是我们的集合名,如果该集合不在该数据库中, MongoDB 会自动创建该集合并插入文档。
查看已插入文档:
> db.col.find()
>{ "_id" : ObjectId("5ed5a7e356fa4269b4e255fd"), "title" : "MongoDB 教程", "description" : "MongoDB 是一个 Nosql 数据库", "by" : "菜鸟教程", "url" : "http://www.runoob.com", "tags" : [ "mongodb", "database", "NoSQL" ], "likes" : 100 }
我们也可以将数据定义为一个变量,如下所示:
document=({title: 'MongoDB 教程', description: 'MongoDB 是一个 Nosql 数据库',by: '菜鸟教程',url: 'http://www.runoob.com',tags: ['mongodb', 'database', 'NoSQL'],likes: 100
});
执行后显示结果如下:
{"title" : "MongoDB 教程","description" : "MongoDB 是一个 Nosql 数据库","by" : "菜鸟教程","url" : "http://www.runoob.com","tags" : ["mongodb","database","NoSQL"],"likes" : 100
}
执行插入操作:
>db.col.insert(document)
WriteResult({ "nInserted" : 1 })
插入文档你也可以使用 db.col.save(document)
命令。如果不指定 _id 字段 save() 方法类似于 insert() 方法。如果指定 _id 字段,则会更新该 _id 的数据。
MongoDB 更新文档
MongoDB 使用 update() 和 save() 方法来更新集合中的文档。接下来让我们详细来看下两个函数的应用及其区别。
update() 方法
语法
update() 方法用于更新已存在的文档。语法格式如下:
db.collection.update(<query>,<update>,{upsert: <boolean>,multi: <boolean>,writeConcern: <document>}
)
- query : update的查询条件,类似sql update查询内where后面的。
- update : update的对象和一些更新的操作符(如 , , ,inc…)等,也可以理解为sql update查询内set后面的
- upsert : 可选,这个参数的意思是,如果不存在update的记录,是否插入objNew,true为插入,默认是false,不插入。
- multi : 可选,mongodb 默认是false,只更新找到的第一条记录,如果这个参数为true,就把按条件查出来多条记录全部更新。
- writeConcern :可选,抛出异常的级别。
实例
我们在集合 col 中插入如下数据:
db.col.insert({title: 'MongoDB 教程', description: 'MongoDB 是一个 Nosql 数据库',by: '菜鸟教程',url: 'http://www.runoob.com',tags: ['mongodb', 'database', 'NoSQL'],likes: 100})
WriteResult({ "nInserted" : 1 })
接着我们通过 update() 方法来更新标题(title):
>db.col.update({'title':'MongoDB 教程'},{$set:{'title':'MongoDB'}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.col.find().pretty()
{"_id" : ObjectId("5ed5a7e356fa4269b4e255fd"),"title" : "MongoDB","description" : "MongoDB 是一个 Nosql 数据库","by" : "菜鸟教程","url" : "http://www.runoob.com","tags" : ["mongodb","database","NoSQL"],"likes" : 100
}
可以看到标题(title)由原来的 “MongoDB 教程” 更新为了 “MongoDB”。
以上语句只会修改第一条发现的文档,如果你要修改多条相同的文档,则需要设置 multi 参数为 true。
>db.col.update({'title':'MongoDB 教程'},{$set:{'title':'MongoDB'}},{multi:true})
save() 方法
语法
save() 方法通过传入的文档来替换已有文档,_id 主键存在就更新,不存在就插入。
db.collection.save(<document>,{writeConcern: <document>}
)
- document : 文档数据。
- writeConcern :可选,抛出异常的级别。
实例
以下实例中我们替换了 _id 为 5ed5a7e356fa4269b4e255fd的文档数据:
原数据
> db.col.find().pretty()
{"_id" : ObjectId("5ed5a7e356fa4269b4e255fd"),"title" : "MongoDB","description" : "MongoDB 是一个 Nosql 数据库","by" : "菜鸟教程","url" : "http://www.runoob.com","tags" : ["mongodb","database","NoSQL"],"likes" : 100
}
执行更新
db.col.save({"_id" : ObjectId("5ed5a7e356fa4269b4e255fd"),"title" : "MongoDB_Zysheep","description" : "MongoDB 是一个 Nosql 数据库","by" : "Zysheep","url" : "http://www.zysheep.cn","tags" : ["mongodb","NoSQL","zysheep"],"likes" : 120
})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
替换成功后,我们可以通过 find() 命令来查看替换后的数据
db.col.find().pretty()
{"_id" : ObjectId("5ed5a7e356fa4269b4e255fd"),
"title" : "MongoDB_Zysheep",
"description" : "MongoDB 是一个 Nosql 数据库",
"by" : "Zysheep",
"url" : "http://www.zysheep.cn",
"tags" : ["mongodb","NoSQL","zysheep"
],
"likes" : 120
}
MongoDB 删除文档
MongoDB remove()
函数是用来移除集合中的数据。MongoDB数据更新可以使用update()
函数。在执行remove()
函数前先执行find()
命令来判断执行的条件是否正确,这是一个比较好的习惯。
语法
db.collection.remove(<query>,<justOne>
)
- query :(可选)删除的文档的条件。
- justOne : (可选)如果设为 true 或 1,则只删除一个文档,如果不设置该参数,或使用默认值 false,则删除所有匹配条件的文档。
- writeConcern :(可选)抛出异常的级别。
实例
# 查询所有数据
> db.col.find()
{ "_id" : ObjectId("5ed5a7e356fa4269b4e255fd"), "title" : "MongoDB_Zysheep", "description" : "MongoDB 是一个 Nosql 数据库", "by" : "Zysheep", "url" : "http://www.zysheep.cn", "tags" : [ "mongodb", "NoSQL", "zysheep" ], "likes" : 120 }
{ "_id" : ObjectId("5ed5a81856fa4269b4e255fe"), "title" : "MongoDB", "description" : "MongoDB 是一个 Nosql 数据库", "by" : "菜鸟教程", "url" : "http://www.runoob.com", "tags" : [ "mongodb", "database", "NoSQL" ], "likes" : 100 }
{ "_id" : ObjectId("5ed5aa2156fa4269b4e25602"), "title" : "MongoDB", "description" : "MongoDB 是一个 Nosql 数据库", "by" : "菜鸟教程", "url" : "http://www.runoob.com", "tags" : [ "mongodb", "database", "NoSQL" ], "likes" : 100 }
# 移除 title 为 'MongoDB' 的文档
>db.col.remove({'title':'MongoDB'})
WriteResult({ "nRemoved" : 2 })
# 再次查询所有文档
>db.col.find()
如果你只想删除第一条找到的记录可以设置 justOne 为 1
>db.COLLECTION_NAME.remove(DELETION_CRITERIA,1)
注意
remove()
方法已经过时了,现在官方推荐使用deleteOne()
和 deleteMany()
方法。
如删除集合下全部文档:
db.COLLECTION_NAME.deleteMany({})
删除 status 等于 A 的全部文档:
db.COLLECTION_NAME.deleteMany({ status : "A" })
删除 status 等于 D 的一个文档:
db.COLLECTION_NAME.deleteOne( { status: "D" } )
MongoDB 查询文档
MongoDB 查询文档使用 find() 方法。
语法
>db.collection.find(query, projection)
- query :可选,使用查询操作符指定查询条件
- projection :可选,使用投影操作符指定返回的键。查询时返回文档中所有键值, 只需省略该参数即可(默认省略)。
如果你需要以易读的方式来读取数据,可以使用 pretty() 方法,语法格式如下:
>db.col.find().pretty()
pretty()
方法以格式化的方式来显示所有文档。
> db.col.find().pretty()
{"_id" : ObjectId("56063f17ade2f21f36b03133"),"title" : "MongoDB 教程","description" : "MongoDB 是一个 Nosql 数据库","by" : "菜鸟教程","url" : "http://www.runoob.com","tags" : ["mongodb","database","NoSQL"],"likes" : 100
}
MongoDB 与 RDBMS Where 语句比较
操作 | 格式 | 范例 | 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
|
MongoDB中条件操作符有:
- (>) 大于 - $gt
- (<) 小于 - $lt
- (>=) 大于等于 - $gte
- (<= ) 小于等于 - $lte
MongoDB AND 条件
MongoDB 的 find() 方法可以传入多个键(key),每个键(key)以逗号隔开,即常规 SQL 的 AND 条件。
语法格式如下:
>db.col.find({key1:value1, key2:value2}).pretty()
#####实例
以下实例通过 by 和 title 键来查询 菜鸟教程 中 MongoDB 教程 的数据
> db.col.find({"by":"菜鸟教程", "title":"MongoDB 教程"}).pretty()
{"_id" : ObjectId("56063f17ade2f21f36b03133"),"title" : "MongoDB 教程","description" : "MongoDB 是一个 Nosql 数据库","by" : "菜鸟教程","url" : "http://www.runoob.com","tags" : ["mongodb","database","NoSQL"],"likes" : 100
}
以上实例中类似于 WHERE 语句:WHERE by=‘菜鸟教程’ AND title=‘MongoDB 教程’
MongoDB OR 条件
MongoDB OR 条件语句使用了关键字 $or,语法格式如下:
>db.col.find({$or: [{key1: value1}, {key2:value2}]}
).pretty()
实例
以下实例中,我们演示了查询键 by 值为 菜鸟教程 或键 title 值为 MongoDB 教程 的文档。
>db.col.find({$or:[{"by":"菜鸟教程"},{"title": "MongoDB 教程"}]}).pretty()
{"_id" : ObjectId("56063f17ade2f21f36b03133"),"title" : "MongoDB 教程","description" : "MongoDB 是一个 Nosql 数据库","by" : "菜鸟教程","url" : "http://www.runoob.com","tags" : ["mongodb","database","NoSQL"],"likes" : 100
}
AND 和 OR 联合使用
以下实例演示了 AND 和 OR 联合使用,类似常规 SQL 语句为: ‘where likes>50 AND (by = ‘菜鸟教程’ OR title = ‘MongoDB 教程’)’
>db.col.find({"likes": {$gt:50}, $or: [{"by": "菜鸟教程"},{"title": "MongoDB 教程"}]}).pretty()
{"_id" : ObjectId("56063f17ade2f21f36b03133"),"title" : "MongoDB 教程","description" : "MongoDB 是一个 Nosql 数据库","by" : "菜鸟教程","url" : "http://www.runoob.com","tags" : ["mongodb","database","NoSQL"],"likes" : 100
}
docker 部署 mongodb
拉取镜像
docker pull mongo
可以查看镜像是否下载成功
docker images | grep mongo
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Mf1YWpCd-1619779608515)(C:\Users\L15096000421\AppData\Roaming\Typora\typora-user-images\1591003616968.png)]
docker 安装 mongodb
docker run --name mongodb -v /data/mongodb0:/data/db -p 27017:27017 -d mongo
执行上述命令之后, 一个挂载了 mongo镜像的容器就开始运行了
--name
设置了容器的名字-v
设置了路径的映射, 将本地路径映射到容器中. 此处, 路径可以自定义-p
设置了端口的映射, 将容器的27017(右侧) 映射到了本地的27017(右侧)
进入容器.
docker exec -it mongodb bash
上述命令的意思如下:使用交互的形式, 在 名字为 mongodb
的容器中实行 bash
这个命令
mongodb
的使用
用户的创建
输入以下命令进入 mongo
创建用户
# 进入 admin 的数据库> use admin
switched to db admin
# 创建管理员用户
> db.createUser(
... {... user: "admin",
... pwd: "123456",
... roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]
... }
... )
Successfully added user: {"user" : "admin","roles" : [{"role" : "userAdminAnyDatabase","db" : "admin"}]
}# 创建有可读写权限的用户. 对于一个特定的数据库, 比如'demo'
> db.createUser({... user: 'test',
... pwd: '123456',
... roles: [{role: "read", db: "demo"}]
... })
Successfully added user: {"user" : "test","roles" : [{"role" : "read","db" : "demo"}]
}
数据库的建立
use demo;
mongo 是否正常启动的校验
先写入一条数据
db.info.save({name: 'test', age: '22'})
查看写入的数据
db.info.find();
结果如下
# 数据库的建立
> use demo;
switched to db demo
# 先写入一条数据
> db.info.save({name: 'test', age: '22'})
WriteResult({ "nInserted" : 1 })
#
> db.info.find();
{ "_id" : ObjectId("5ed4cc9c3f1db5d1d0e02f01"), "name" : "test", "age" : "22" }
远程连接的开启
在 mongodb
的容器当中
#更新源
apt-get update
# 安装 vim
apt-get install vim
# 修改 mongo 配置文件
vim /etc/mongod.conf.orig
将其中的bindIp: 127.0.0.1
注释掉# bindIp: 127.0.0.1
或者改成bindIp: 0.0.0.0
即可开启远程连接
基于MongoTemplate 开发CRUD
1、引入springboot mongo依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
2、mongo的IP和端口
在resources下的application.yml中加入如下内容,端口默认:27017
spring:data:mongodb:uri: mongodb://172.16.0.192/test
3、使用mongoTemplate
User
/*** @version v1.0.0* @ProjectName: springboot-learning-examples* @ClassName: User* @Author: 三月三*/
@Data
@Document("User")
public class User {@Idprivate String id;private String name;private Integer age;private String email;private String createDate;
}
常用方法
mongoTemplate.findAll(User.class): 查询User文档的全部数据
mongoTemplate.findById(<id>, 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")))
测试
@SpringBootTest
class DemomogoApplicationTests {@Autowiredprivate MongoTemplate mongoTemplate;//添加@Testpublic void createUser() {User user = new User();user.setAge(20);user.setName("zysheep");user.setEmail("zysheep@126.com");User user1 = mongoTemplate.insert(user);System.out.println(user1);}//查询所有@Testpublic void findUser() {List<User> userList = mongoTemplate.findAll(User.class);System.out.println(userList);}//根据id查询@Testpublic void getById() {User user = mongoTemplate.findById("5ffbfa2ac290f356edf9b5aa", User.class);System.out.println(user);}//条件查询@Testpublic void findUserList() {Query query = new Query(Criteria.where("name").is("zysheep").and("age").is(20));List<User> userList = mongoTemplate.find(query, User.class);System.out.println(userList);}//模糊查询@Testpublic void findUsersLikeName() {String name = "eep";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);}//分页查询@Testpublic void findUsersPage() {String name = "est";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);}//修改@Testpublic void updateUser() {User user = mongoTemplate.findById("5ffbfa2ac290f356edf9b5aa", User.class);user.setName("test_1");user.setAge(25);user.setEmail("493220990@qq.com");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);}//删除操作@Testpublic 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);}
}
为了方便测试,封装了MongodbUtils
package cn.zysheep.springboot.utils;import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
import javax.annotation.PostConstruct;import cn.zysheep.springboot.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.GroupOperation;
import org.springframework.data.mongodb.core.aggregation.MatchOperation;
import org.springframework.data.mongodb.core.index.Index;
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.stereotype.Component;
import org.springframework.util.StringUtils;/*** @version v1.0.0* @ProjectName: springboot-learning-examples* @ClassName: MongodbUtils* @Author: 三月三*/@Component
public class MongodbUtils {public static MongodbUtils mongodbUtil;@PostConstructpublic void init() {mongodbUtil = this;mongodbUtil.mongoTemplate = this.mongoTemplate;}@Autowiredprivate MongoTemplate mongoTemplate;/*** 保存对象List到指定集合中* <p>* 也可以在实体类上使用@Document(collection=“集合名称”)指定集合名称,未指定则默认实体类的类名为集合名称** @param entiys*/public static void saveAll(String collName, List<?> entiys) {for (Object entiy : entiys) {saveData(collName, entiy);}}/*** 保存单个对象到指定集合中** @param collName 集合名称* @param entiy 实体名称*/public static void saveOne(String collName, Object entiy) {saveData(collName, entiy);}/*** 根据id倒序查询 集合中的数据** @param entiy 数据实体* @param collName 集合名称* @param direction 倒序/正序 Direction.DESC/ASC* @param*/public static Object findSortById(Class<?> entiy, String collName, Sort.Direction direction) {Query query = new Query().with(Sort.by(direction, "id"));return mongodbUtil.mongoTemplate.find(query, entiy, collName);}/*** 查询返回指定字段** @param fields 需要返回的指定字段* @param clazz 数据实体类class* @param collName 集合名称* @param map Map<查询条件key,查询条件value>* <p>* 返回字段的时候id默认为返回,不返回id则field设置 fieldObj.put("id",false)* @return*/public static Object findDesignField(List<String> fields, Map<String, Object> map, Class<?> clazz, String collName, boolean returnId) {Criteria criteria = null;if (map.containsKey(null)) {return "查询条件key不能为Null~";}for (String key : map.keySet()) {criteria = Criteria.where(key).is(map.get(key));}Query query = new Query(criteria);for (String field : fields) {query.fields().include(field);}if (!returnId) {query.fields().exclude("id");}return mongodbUtil.mongoTemplate.find(query, clazz, collName);}/*** 查询指定集合中的所有数据** @param entiy 数据实体类* @param collName 集合名称*/public static Object findAll(Class<?> entiy, String collName) {return mongodbUtil.mongoTemplate.findAll(entiy, collName);}/*** 模糊查询 根据 key 可以到 collName 中进行模糊查询 并排序** @param param 匹配的参数* @param collName 集合名称* @param direction Direction.desc /asc 倒序/正序* @param sortField 排序字段* @return*/public static Object findLikeByParam(String param, String collName, String sortField, Sort.Direction direction,Class<?> entiy) {Pattern pattern = Pattern.compile("^.*" + param + ".*$", Pattern.CASE_INSENSITIVE);Query query = new Query(Criteria.where("name").regex(pattern)).with(Sort.by(direction, sortField));return mongodbUtil.mongoTemplate.find(query, entiy, collName);}/*** 向指定集合设置索引** @param collName 集合名称* @param indexName 索引名称* @param map map.put("添加索引的字段",Direction.ASC/DESC)*/public static void createIndex(String collName, String indexName, Map<String, Sort.Direction> map) throws Exception {if (map.containsKey(null)) {throw new Exception("添加索引的字段不能为null");}Index index = new Index().named(indexName);for (String key : map.keySet()) {index.on(key, map.get(key));}mongodbUtil.mongoTemplate.indexOps(collName).ensureIndex(index);}/*** 获取指定集合中的索引信息** @param collName 集合名称* @return*/public static Object getIndexInfo(String collName) {return mongodbUtil.mongoTemplate.indexOps(collName).getIndexInfo();}/*** 根据索引名称删除索引** @param indexName 索引名称* @param collName 集合名称*/public static void removeIndexByName(String collName, String indexName) {mongodbUtil.mongoTemplate.indexOps(collName).dropIndex(indexName);}/*** 删除指定集合中得所有索引** @param collName 集合名称*/public static void removeIndexByName(String collName) {mongodbUtil.mongoTemplate.indexOps(collName).dropAllIndexes();}/*** 根据指定key 和value到指定collName集合中删除数据** @param key* @param value* @param collName*/public static void removeAllByParam(String key, String value, String collName) {Criteria criteria = Criteria.where(key).is(value);Query query = Query.query(criteria);mongodbUtil.mongoTemplate.remove(query, collName);}/*** 根据指定条件查询 并排序** @param obj 数据对象* @param map Map<"查询条件key",查询条件值> map* @param collName 集合名称* @return*/public static List<? extends Object> findSortByParam(Object obj, String collName, Map<String, Object> map, String sortField, Sort.Direction direction) {if (map.containsKey(null)) {return new ArrayList<>();}Criteria criteria = null;criteria = getCriteria(criteria, map);if (criteria == null) {return new ArrayList<>();}Query query = Query.query(criteria).with(Sort.by(direction, sortField));return mongodbUtil.mongoTemplate.find(query, obj.getClass(), collName);}/*** 范围查询* <p>* 查询大于等于begin 小于等于end范围内条件匹配得数据并排序** @param obj 数据对象* @param collName 集合名称* @param map Map<"查询条件key",查询条件值> map* @param sortField 排序字段* @param direction 排序方式 Direction.asc / Direction.desc* @param rangeCriteria 示例: lt小于 lte 小于等于 gt大于 gte大于等于 eq等于 ne不等于* <p>* Criteria rangeCriteria=Criteria.where("createDate").gte(begin).lte(end));* <p>* createDate:数据库中的时间字段,gegin:起始时间 end:结束时间* @return*/public static List<? extends Object> findRangeByParam(Object obj, String collName, Map<String, Object> map,String sortField, Sort.Direction direction, Criteria rangeCriteria) {if (map.containsKey(null)) {return new ArrayList<>();}Criteria criteria = null;criteria = getCriteria(criteria, map);if (criteria == null) {return new ArrayList<>();}Query query = new Query().addCriteria(rangeCriteria).addCriteria(criteria).with(Sort.by(direction, sortField));return mongodbUtil.mongoTemplate.find(query, obj.getClass(), collName);}/*** 根据指定key value到指定集合中查询匹配得数量** @param collName* @param key* @param value* @return*/public static long count(String collName, String key, String value) {Query query = Query.query(Criteria.where(key).is(value));return mongodbUtil.mongoTemplate.count(query, "goods");}/*** 在指定范围内查询匹配条件的数量** @param clazz 数据实体类* @param collName 集合名称* @param map 查询条件map* @param rangeCriteria 范围条件 Criteria rangeCriteria= Criteria.where("数据库字段").gt/gte(起始范围).lt/lte(结束范围)* @return*/public static Long countRangeCondition(Class<?> clazz, String collName, Criteria rangeCriteria, Map<String, Object> map) {Criteria criteria = null;if (map.containsKey(null)) {return null;}for (String key : map.keySet()) {criteria = Criteria.where(key).is(map.get(key));}Query query = new Query();if (criteria != null) {query.addCriteria(criteria);}query.addCriteria(rangeCriteria);return mongodbUtil.mongoTemplate.count(query, clazz, collName);}/*** 指定集合 根据条件查询出符合的第一条数据** @param entiy 数据对象* @param map 条件map Map<条件key,条件value> map* @param collectionName 集合名* @return*/public static Object findSortFirst(Class<?> entiy, Map<String, Object> map, String collectionName, String field, Sort.Direction direction) {if (map.containsKey(null)) {return "查询条件不能为null~";}Criteria criteria = null;criteria = getCriteria(criteria, map);Query query = Query.query(criteria).with(Sort.by(direction, field));return mongodbUtil.mongoTemplate.findOne(query, entiy, collectionName);}/*** 指定集合 修改数据,且修改所找到的所有数据** @param accordingKey 修改条件 key* @param accordingValue 修改条件 value* @param map Map<修改内容 key数组,修改内容 value数组>* @param collName 集合名* @param type 修改操作类型 1:修改第一条数据 0:修改所有匹配得数据*/public static void updateMulti(String accordingKey, Object accordingValue, Map<String, Object> map,String collName, Integer type) {if (map.containsKey(null)) {return;}Criteria criteria = Criteria.where(accordingKey).is(accordingValue);Query query = Query.query(criteria);Update update = new Update();for (String key : map.keySet()) {update.set(key, map.get(key));}if (type == 1) {mongodbUtil.mongoTemplate.updateFirst(query, update, collName);} else {mongodbUtil.mongoTemplate.updateMulti(query, update, collName);}}/*** 对某字段做sum求和** @param clazz 数据实体类* @param map Map<查询条件key,查询条件value> map* @param collName 集合名称* @param sumField 求和字段* @param rangeCriteria 范围条件* @return Criteria rangeCriteria = Criteria.where(字段).gt(起始范围).lt(结束范围)*/public static Object findSum(Class<?> clazz, Map<String, Object> map, String collName, String sumField, Criteria rangeCriteria) {if (map.containsKey(null)) {return "查询条件key不能为Null";}Criteria criteria = null;MatchOperation match = null;for (String key : map.keySet()) {criteria = Criteria.where(key).is(map.get(key));}if (criteria != null) {match = Aggregation.match(criteria);}GroupOperation count = Aggregation.group().sum(sumField).as(sumField);return mongodbUtil.mongoTemplate.aggregate(Aggregation.newAggregation(match, count), collName, clazz).getMappedResults();}/*** 分页查询** @param entiy 数据实体类* @param collName 集合名称* @param map Map<"查询条件key",查询条件值> map 若 keys/values 为null,则查询集合中所有数据* @param pageNo 当前页* @param pageSize 当前页数据条数* @param direction Direction.Desc/ASC 排序方式* @param sortField 排序字段* @return*/public static PageModel findSortPageCondition(Class<?> entiy, String collName, Map<String, Object> map,int pageNo, int pageSize, Sort.Direction direction, String sortField) {Criteria criteria = getCriteria(new Criteria(), map);long count;if (criteria == null) {count = mongodbUtil.mongoTemplate.count(new Query(), entiy, collName);} else {count = mongodbUtil.mongoTemplate.count(new Query(criteria), entiy, collName);}int pages = (int) Math.ceil((double) count / (double) pageSize);if (pageNo <= 0 || pageNo > pages) {pageNo = 1;}int skip = pageSize * (pageNo - 1);Query query = new Query().skip(skip).limit(pageSize);query.with(Sort.by(direction, sortField));if (criteria != null) {query.addCriteria(criteria);}List<?> list = mongodbUtil.mongoTemplate.find(query, entiy, collName);PageModel pageModel = new PageModel();pageModel.setPageNo(pageNo);pageModel.setPagesize(pageSize);pageModel.setTotal(count);pageModel.setPages(pages);pageModel.setList(list);return pageModel;}private static void saveData(String collName, Object entiy) {if (StringUtils.isEmpty(collName)) {mongodbUtil.mongoTemplate.save(entiy);} else {mongodbUtil.mongoTemplate.save(entiy, collName);}}private static Criteria getCriteria(Criteria criteria, Map<String, Object> map) {if (map == null) {return null;}int i = 0;for (String key : map.keySet()) {if (i == 0) {criteria = Criteria.where(key).is(map.get(key));i++;} else {criteria.and(key).is(map.get(key));}}return criteria;}
}
package cn.zysheep.springboot.utils;import java.io.Serializable;
import java.util.List;/*** @version v1.0.0* @ProjectName: springboot-learning-examples* @ClassName: PageModel* @Author: 三月三*/
public class PageModel implements Serializable {private static final long serialVersionUID = 1L;/*** 当前页*/private Integer pageNo = 1;/*** 当前页条数*/private Integer pagesize = 10;/*** 总共的条数*/private Long total;/*** 总共的页数*/private Integer pages;/*** 实体类集合*/private List<?> list;public Integer getPageNo() {return pageNo;}public void setPageNo(Integer pageNo) {this.pageNo = pageNo;}public Integer getPagesize() {return pagesize;}public void setPagesize(Integer pagesize) {this.pagesize = pagesize;}public Long getTotal() {return total;}/*** 总数由0开始计数* @param total*/public void setTotal(Long total) {this.total = total + 1;}public Integer getPages() {return pages;}public void setPages(Integer pages) {this.pages = pages;}public List<?> getList() {return list;}public void setList(List<?> list) {this.list = list;}public PageModel(Integer pageNo, Integer pagesize, Long total, Integer pages, List<?> list) {this.pageNo = pageNo;this.pagesize = pagesize;this.total = total;this.pages = pages;this.list = list;}public PageModel() {}@Overridepublic String toString() {return "PageModel{" +"pageNo=" + pageNo +", pagesize=" + pagesize +", total=" + total +", pages=" + pages +", list=" + list +'}';}
}
测试
package cn.zysheep.springboot;import cn.zysheep.springboot.entity.User;
import cn.zysheep.springboot.repository.UserRepository;
import cn.zysheep.springboot.utils.MongodbUtils;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;import java.util.ArrayList;
import java.util.List;@SpringBootTest
class Springboot06DataMongodbApplicationTests {@Autowiredprivate UserRepository userRepository;@Autowiredprivate MongodbUtils mongodbUtils;// 测试添加文档@Testpublic void testSaveUser() throws Exception {User user=new User();user.setId(1l);user.setUserName("明世隐");user.setPassWord("123456");userRepository.saveUser(user);}// 测试根据名字查询文档@Testpublic void findUserByUserName(){User user= userRepository.findUserByUserName("明世隐");System.out.println("user is "+user);}// 测试修改文档@Testpublic void updateUser(){User user=new User();user.setId(2l);user.setUserName("韩信");user.setPassWord("123456789");userRepository.updateUser(user);}// 测试删除@Testpublic void deleteUserById(){userRepository.deleteUserById(1l);}@Testvoid test1(){List<User> user = (List<User>)MongodbUtils.findAll(User.class, "user");user.forEach(System.out::println);}@Testvoid test2(){MongodbUtils.saveOne("user",new User(5L,"干将莫邪","123123"));}@Testvoid test3(){ArrayList<User> list = new ArrayList<>();list.add(new User(6L,"荆轲","123123"));list.add(new User(7L,"赵云","12312"));list.add(new User(8L,"公孙离","asdfasdf"));list.add(new User(9L,"伽罗","hdfgsdfg"));MongodbUtils.saveAll("user",list);}}
基于MongoRepository开发CRUD
Spring Data提供了对mongodb数据访问的支持,我们只需要继承MongoRepository类,按照Spring Data规范就可以了
SpringData 方法定义规范
- 不是随便声明的,而需要符合一定的规范
- 查询方法以find | read | get开头
- 涉及条件查询时,条件的属性用条件关键字连接
- 要注意的是:条件属性首字母需要大写
- 支持属性的级联查询,但若当前类有符合条件的属性则优先使用,而不使用级联属性,若需要使用级联属性,则属性之间使用_强制进行连接
添加Repository类
UserRepository
@Repository
public interface UserRepository extends MongoRepository<User, String> {}
测试
@SpringBootTest
class DemomogoApplicationTests1 {@Autowiredprivate UserRepository userRepository;//添加@Testpublic void createUser() {User user = new User();user.setAge(20);user.setName("张三");user.setEmail("3332200@qq.com");User user1 = userRepository.save(user);}//查询所有@Testpublic void findUser() {List<User> userList = userRepository.findAll();System.out.println(userList);}//id查询@Testpublic void getById() {User user = userRepository.findById("5ffbfe8197f24a07007bd6ce").get();System.out.println(user);}//条件查询@Testpublic 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);}//模糊查询@Testpublic 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);}//分页查询@Testpublic 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);}//修改@Testpublic void updateUser() {User user = userRepository.findById("5ffbfe8197f24a07007bd6ce").get();user.setName("张三_1");user.setAge(25);user.setEmail("883220990@qq.com");User save = userRepository.save(user);System.out.println(save);}//删除@Testpublic void delete() {userRepository.deleteById("5ffbfe8197f24a07007bd6ce");}
}
多数据源 MongoDB 的使用
pom
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
yml
spring:data:mongodb:host1: 172.16.0.192host2: 172.16.0.192dbName:primaryDb: primarysecondaryDb: secondary
MongoConfig
package cn.zysheep.springboot.config;import com.mongodb.MongoClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.SimpleMongoDbFactory;/*** @version v1.0.0* @ProjectName: springboot-learning-examples* @ClassName: MongoConfig* @Author: 三月三*/
@Configuration
public class MongoConfig {//读取配置文件里的值,部署后IP或者数据库名变化,不需重新打包@Value("${spring.data.mongodb.host1}")private String mongohost1;@Value("${spring.data.mongodb.host2}")private String mongohost2;@Value("${spring.data.dbName.primaryDb}")private String primaryDb;@Value("${spring.data.dbName.secondaryDb}")private String secondaryDb;@Bean@Primarypublic MongoClient mongoClient() {return new MongoClient(mongohost1);}@Beanpublic MongoClient mongoClient2() {return new MongoClient(mongohost2);}@Bean@Primarypublic MongoTemplate primaryMongoTemplate() {return new MongoTemplate(mongoClient(), primaryDb);}@Beanpublic MongoTemplate secondaryMongoTemplate() {return new MongoTemplate(new SimpleMongoDbFactory(mongoClient(), secondaryDb));}
}
Person
package cn.zysheep.springboot.entity;import lombok.Data;
import org.springframework.stereotype.Component;/*** @version v1.0.0* @ProjectName: springboot-learning-examples* @ClassName: Person* @Author: 三月三*/@Component
@Data
public class Person {private String id;private String name;private int age;public Person() {}public Person(String id, String name, int age) {this.id = id;this.name = name;this.age = age;}@Overridepublic String toString() {return "Person{" +"id='" + id + '\'' +", name='" + name + '\'' +", age=" + age +'}';}
}
测试
package cn.zysheep.springboot;
import cn.zysheep.springboot.entity.Person;
import org.junit.jupiter.api.Test;
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 javax.annotation.Resource;@SpringBootTest
class Springboot06DataMultiMongodb22XApplicationTests {//这里用Resource,没有用Autoware@Resourceprivate MongoTemplate primaryMongoTemplate;@Resourceprivate MongoTemplate secondaryMongoTemplate;//右键运行,看看两个库是否同时插入了数据@Testpublic void insert(){Person p=new Person("001","tom",88);primaryMongoTemplate.insert(p);Person p2=new Person("N0012","zhangsan",14);secondaryMongoTemplate.insert(p2);}@Testpublic void queryon(){Person qp = primaryMongoTemplate.findOne(new Query(new Criteria("name").is("tom")), Person.class);System.out.println(qp);}@Testpublic void getOne(){//不指定数据集,根据实体类的类名获取数据集。 这里Person也会被当作collectionNamePerson zz = primaryMongoTemplate.findOne(new Query(new Criteria("name").is("tom")), Person.class);//指定数据集 同一个数据库下,建了一个user集合,跟person结构相同,这时就要指定了Person one = primaryMongoTemplate.findOne(new Query(new Criteria("name").is("tom")), Person.class,"primary");System.out.println(one);}
}
【SpringBoot高级篇】SpringBoot集成MongDB数据库相关推荐
- 【SpringBoot高级篇】SpringBoot集成Elasticsearch搜索引擎
[SpringBoot高级篇]SpringBoot集成Elasticsearch搜索引擎 1. 什么是Elasticsearch? 2. 安装并运行Elasticsearch 2.1 拉取镜像 2.2 ...
- 【SpringBoot高级篇】SpringBoot集成jasypt 配置脱敏和数据脱敏
[SpringBoot高级篇]SpringBoot集成jasypt数据脱敏 配置脱敏 使用场景 配置脱敏实践 数据脱敏 pom yml EncryptMethod EncryptField Encry ...
- 【SpringBoot高级篇】springboot实现上传docdocx文件格式转html在线预览v2.0
[SpringBoot高级篇]springboot实现上传doc&docx文件格式转html在线预览v2.0 pom 上传路径工具类 SpringMvc虚拟路径映射 doc转html工具类 d ...
- 【SpringBoot高级】SpringBoot整合篇
SpringBoot整合篇
- SpringBoot高级篇JdbcTemplate之数据查询上篇
前面一篇介绍如何使用JdbcTemplate实现插入数据,接下来进入实际业务中,最常见的查询篇.由于查询的姿势实在太多,对内容进行了拆分,本篇主要介绍几个基本的使用姿势 queryForMap que ...
- SpringBoot高级篇MongoDB之修改基本使用姿势
原文: 190218-SpringBoot高级篇MongoDB之修改基本使用姿势 本篇依然是MongoDB curd中的一篇,主要介绍document的更新,主要内容如下 常见类型成员的修改 数组类型 ...
- springboot高级篇及springboot1.5转springboot2.17所遇到的坑
SpringBoot的高级教程 一.SpringBoot缓存 缓存的场景 临时性数据存储[校验码] 避免频繁因为相同的内容查询数据库[查询的信息] 1.JSR107缓存规范 用的比较少 Java Ca ...
- Java高级篇-----Springboot框架
目录 1.什么是Springboot 2.Springboot框架的特点 3.创建Springboot工程 3.1.准备条件 3.2. 创建springboot的方式有两种 3.2.1. 使用idea ...
- springboot高级篇(认证,授权)
认证,授权 1,项目 1.1登陆 1.2,注销 1.3,认证授权 1.4,记住我功能 认证:证明你是谁,携带用户名和密码.系统查验是你这个人的过程. 授权:认证以后你能干什么,访问资源的权限 1,项目 ...
最新文章
- C#--多线程--2
- 缺少物联网杀手级应用的运营商,到底该怎么办?
- spring bean作用域_Srping中Bean的三种装配方式:大魏Java记10
- 0、elasticsearch前言
- javascript小游戏_javaScript小游戏——网页版别踩白块
- java共同方法_java-现有公共方法的NoSuchMethodError
- android长按非控件处,Android常用之Butterknife使用详解
- Cookie 版购物车
- 网易云基于 Kubernetes 的深度定制化实践
- mysql拼装字段_Mysql 实现字段拼接的三个函数
- JS网页恶搞代码,不断弹出、关不掉的对话框
- 对话罗永浩:手机行业唯一的聪明人死了,我胜算很大
- NO.3 微信第三方平台代创建小程序审核发布以及小程序信息(头像,名称,简介)修改 以及微信错误码 返回信息
- 基于 WebRTC 创建一款多人联机游戏
- 写switch case语句不加break会怎样。
- 大班线描机器人_大班线描画-有趣的巨人
- 音视频播放疑难杂症分析和解决思路
- C++调用Python(混合编程)函数整理总结
- 关于for循环中三个语句的执行顺序
- (转)FFmpeg 基本用法
热门文章
- PHP MySQL 插入数据
- python操作mysql数据库用到的fetchone()函数和fetchall()函数
- 谈PHP发展前景和就业解析 -兄弟连IT教育
- Linux学习之计算机基础理论
- 台式计算机无法访问网络,完美:台式计算机的解决方案无法访问Internet,但手机可以连接到wifi无线网络...
- SpringBoot系列之Hikari连接池
- 深坑之Webview,解决H5调用android相机拍照和录像
- 2021年高压电工考试题及高压电工考试题库
- 使用SearchGuard对ElasticSearch进行权限访问控制
- orgChart实现竖向排列组织图(js实现组织机构图)