MongoDB是为快速开发互联网Web应用而设计的数据库系统
MongoDB的设计目标是极简、灵活、作为Web应用栈的一部分
MongoDB的数据模型是面向文档的,所谓文档是一种类似于JSON的结构
MongoDB的版本偶数版本为稳定版,奇数版本为开发版。
官网:https://www.mongodb.com/try/download/community
Linux中安装
# 1.下载
# 2.解压
tar -zxvf mongodb-linux-***.tgz
# 3.将解压包移动到指定目录
mv mongodb-***/ /usr/local/mongodb
# 4.创建数据存放目录与日志存放目录
mkdir -p /usr/local/mongodb/data /usr/local/mongodb/logs
# 5.启动MongoDB服务
/usr/local/mongodb/bin/mongod --dbpath=/usr/local/mongodb/data --logpath=/usr/local/mongodb/logs/mongodb.logs --logappend --port=27017 --fork
# 后期登录
/usr/local/mongodb/bin/mongo
windows中安装 (略)
查看数据库
show databases
使用数据库
use 数据库名称
在mongodb中选择不存在的数据库不会报错,隐式创建(后期当该数据库中有数据时自动创建)
创建数据库
隐式创建
删除数据库
查看集合
show collections
创建集合
db.createCollection(‘集合名’)
删除集合
db.集合名.drop()
集合的导入与导出
# 导出
# ip+端口 数据库名 集合名 导出文件
mongoexport -h localhost:27017 -d tangmin -c student -o d:/c1.json
# 导入
# ip+端口 数据库名 集合名 导入文件
mongoimport -h localhost:27017 -d local -c tm d:/c1.json
C增
语法:db.集合名.insert(JSON数据)
说明:集合存在-直接插入数据,集合不存在-隐式创建
练习:在test2数据库的c1集合中插入数据(姓名zhangsan年龄18)
use test2
db.c1.insert({name:'zhangsan',age:18})
注意1:数据库和集合不存在隐式创建
注意2:对象的键统一不加引号方便看,但查看集合数据时系统会自动加
注意3:mongodb会给每条数据增加一个全球唯一的_id键(时间戳+机器码+PID+计数器)
思考1:是否可以自定义_id值?
可以,只需要给插入的JSON数据增加_id键即可覆盖(实战强烈不建议)
思考2:如何一次性插入多条数据?
传递数组,数组中写一个个JSON数据即可
db.c1.insert([
{name:'zhangsan',age:23},
{name:'lisi',age:24},
{name:'wangwu',age:25}
])
思考3:如何快速插入10条数据
mogodb底层使用JS引擎实现的,支持部分js语法 因此可以写for循环
for(var i=1;i<10;i++){
print(i)
}
需求:在test2数据库c2集合中插入10条数据,分别为a1,a2...a10
use test2
for(var i=1;i<10;i++){
db.c2.insert({username:'a'+1,age:i})
}
R查
基础语法:db.集合名.find(条件[,查询的列])
条件
查询所有数据 {}或不写
查询age=6的数据 {age:6}
既要age=6又要性别=男 {age:6,sex:'男'}
查询的列(可选参数
不写 - 查询所有列
{age:1} 只显示age列
{age:0} 除了age列都显示
注意:不管你怎么写系统自定义的_id都会在
升级语法
db.集合名.find({键:值}) 注:值不直接写
db.集合名.find({
键:{
运算符:值
}
})
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4pJwhJok-1603856560466)(D:\Desk\学习总结\图片\image-20200927011055762.png)]
练习
查询所有数据(格式化)
db.c1.find().pretty()
只显示name列
db.c1.find({},{name:1})
查询年龄大于18的数据
db.c1.find({age:{$gt:18}})
查询年龄为5,8,10的数据
db.c1.find({age:{$in:[5,8,10]}})
U改
基础语法:db.集合名.update(条件,新数据[,是否新增,是否修改多条])
是否新增:指条件匹配不到数据则插入(true是 插入,false否 不插入默认)
是否修改多条:指将匹配的数据都修改(true是,false否某人)
升级语法
db.集合名.update(条件,新数据)
{修改器:{键:值}}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uje1LdHH-1603856560483)(D:\Desk\学习总结\图片\image-20201010223426600.png)]
练习
准备工作
use test1
for(var i=1;i<=10;i++){
db.c1.insert({"name":"zs"+i,"age":i})
}
练习1:将{name:“zs1”}改为{name:“zs2”}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5EPcTXl7-1603856560490)(D:\Desk\学习总结\图片\image-20201010223113240.png)]
发现:默认是替换,不是修改
解决:使用升级语法 修改器
需求:使用修改器将zs2的姓名改为zs22
语法:db.c1.update({name:‘zs2’},{$set:{name:‘zs22’}})
练习2:给{name:‘zs10’}的年龄加2岁或者减2岁
db.c1.update({name:'zs10'},{$inc:{age:2}})
练习3:修改器综合练习
插入数据:db.c2.insert(name:‘zs’,age:23,sex:‘男’,heigh:111);
完成需求:
name 改成 lisi
age 增加 124
sex 改成 gender
height 删除
db.c2.update({name:'zs'},{name:'lisi'}) #错误替换
{$set:{name:'lisi'}}
{$inc:{age:124}}
{$rename:{sex:gender}}
{$unset:{height:true}}
#多个组合器组合
db.c2.update({name:'zs'},{
$set:{name:'lisi'},
$inc:{age:124},
$rename:{sex:'gender'},
$unset:{height:true}
})
练习4:验证语法最后两个参数(了解)
验证:是否新增true是 false否,修改name等于zs30的年龄30岁
db.c1.update({name:'zs30'},{$set:{age:30}}) 默认false
db.c1.update({name:'zs30'},{$set:{age:30}},true)
验证:是否修改多条数据true是,false否默认
# 将所有c1集合中的所有数据改为10岁
db.c1.update({},{$set:{age:10}},false,true)
D删除
语法:db.集合名.remove(条件[,是否删除一条])
注意:是否删除一条true是,false否 默认
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-N8B27P7R-1603856560496)(D:\Desk\学习总结\图片\image-20201010232849959.png)]
根据UI设计稿
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CJbw6onh-1603856560499)(D:\Desk\学习总结\图片\image-20201010234537510.png)]
UI设计稿每个展示内容对应一个字段
创建于字段
更新于字段
状态字段
最后:先中文、后英文
注意:上述规则照顾基础差的,如果大神 或 久而久之 就变成肌肉记忆 下意识直接创建
需求:根据教学系统,设计存放学生信息的集合,并插入20条测试数据
代码
1.先中文
集合名:学生集合
集合字段(看UI设计稿):编号、学号、姓名、电话、性别、年龄、学历、备注
2.再英文
use student
for(var num=1;num<=20;num++){
db.stu.insert({
id:num,
no:'2020_'+num,
uname:'zhangsan'+num,
tel:'123456',
sex:'女',
age:num,
edu:'研究生',
remark:'非常好'
})
}
语法:db.集合名.find().sort(JSON数据)
说明:键-就是要排序的列 值:1升序 -1降序
练习:年龄升序&降序
# 准备数据
use test2;
db.c1.insert({_id:1,name:'a',sex:1,age:1})
db.c1.insert({_id:2,name:'a',sex:1,age:2})
db.c1.insert({_id:3,name:'b',sex:2,age:3})
db.c1.insert({_id:4,name:'c',sex:2,age:4})
db.c1.insert({_id:5,name:'d',sex:2,age:5})
db.c1.find()
# 年龄升序
db.c1.find().sort({age:1})
# 1.年龄降序查询2条
db.c1.find().sort({age:-1}).limit(2)
# 2.年龄降序跳过2条并查询两条
db.c1.find().sort({age:-1}).skip(2).limit(2)
聚合查询:把数据聚起来统计
语法
db.集合名.aggregate([
{管道:{表达式}}
])
常用管道
$group 将集合中的文档分组,用于统计结果
$match 过滤数据,只要输出符合条件的文档
$sort 聚合数据进一步排序
$skip 跳过指定文档数
$limit 限制集合数据返回文档数
....
常用表达式
$sum 总和 $sum:1同count表示统计
$avg 平均
$min 最小值
$max 最大值
....
练习
准备数据
use test3
db.c1.insert({_id:1,name:'a',sex:1,age:1})
db.c1.insert({_id:2,name:'a',sex:1,age:2})
db.c1.insert({_id:3,name:'b',sex:2,age:3})
db.c1.insert({_id:4,name:'c',sex:2,age:4})
db.c1.insert({_id:5,name:'d',sex:2,age:5})
练习1 统计男生、女生的总年龄
db.c1.aggregate([
{
$group:{
_id:'$sex',
rs:{$sum:'$age'}
}
}
])
练习2 统计男生、女生的总人数
db.c1.aggregate([
{
$group:{
_id:'$sex',
rs:{$sum:1}
}
}
])
练习3 求学生总数和平均年龄
db.c1.aggregate([
{
$group:{
_id:null,
total_num:{
$sum:1
},
total_avg:{
$avg:'$age'
}
}
}
])
练习3 查询男生、女生人数,按人数升序
db.c1.aggregate([
{
$group:{
_id:'$sex',
rs:{
$sum:1
}
}
},
{
$sort:{
rs:1
}
}
])
语法
# 创建索引
db.集合名.createIndex(待创建索引的列[,额外选项])
# 参数
带创建索引的列:{键:1,...,键:-1}
1 升序 -1降序 例如{age:1}表示创建age索引并按照升序的方式存储
额外选项:设置索引的名称或唯一索引等等
# 删除索引
全部删除:db.集合名.dropIndexes()
删除指定:db.集合名.dropIndex(索引名)
# 查看索引
db.集合名.getIndexes()
练习
准备数据
// 选择数据库
use test4
// 向数据库中插入数据
for(var i=0;i<100000;i++){
db.c1.insert({name:'aaa'+i,age:i})
}
练习1 给name添加普通索引
db.c1.createIndex({name:1})
练习2 删除name索引
db.c1.dropIndex('name_1')
练习3 给name创建索引并起名name_index
db.c1.createIndex({name:1},{name:'name_index'})
创建复合/组合索引
语法
db.集合名.create({键1:方式,键2:方式})
给name和age添加组合索引
db.c1.createIndex({name:1,age:1})
创建唯一索引
语法
db.集合名.create(待添加索引的列,{unique:列名})
练习
练习1 删除全部索引(系统的不会删)
db.c1.dropIndexes()
练习2 创建唯一索引
db.c1.createIndex({name:1},{unique:'name'})
练习3 测试唯一索引 插入两次相同数据
db.c1.insert({name:'a'})
db.c1.insert({name:'a'})
语法
db.集合名.find().explain('executionStats')
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kqSAy12d-1603856560501)(D:\Desk\学习总结\图片\image-20201011231641491.png)]
索引的扫描方式
选择规则(如何选择合适的列创建索引)
语法
// 创建账号
db.createUser({
"user": '账号',
"pwd": '密码',
"roles": [{
role: '角色',
db: '所属数据库'
}]
})
角色
# 角色种类
超级用户角色:root
数据库用户角色:read、readWrite
数据库管理角色:dbAdmin、userAdmin
集群管理角色:clusterAdmin、clusterManager、clusterMonitor、hostManager
备份恢复角色:backup、restore
所有数据库角色:readAnyDatabase、readWriteAnyDatabase、userAdminAnyDatabase、dbAdminAnydDatabase
# 角色说明
root:只在admin数据库中可用。超级账号,超级权限
read:允许用户读取指定数据库
readWrite:允许用户读写指定数据库
开启验证模式(用户需要输入账号密码才能登录使用)
# 步骤1 添加超级管理员
use admin
db.createUser({
'user': 'admin',
'pwd': 'admin888',
'roles': [{
role: 'root',
db: 'admin'
}]
})
# 步骤2 退出卸载服务
bin\mongod --remove
注意:DOS窗口必需以管理员身份允许
# 步骤3 重新安装需要输入账号密码的服务(注:在原来安装命令基础上加--auth即可)
bin\mongod --install --dbpath D:\MongoDB\Server\3.4\data --logpath D:\MongoDB\Server\3.4\logs\mongo2.log --auth
# 步骤4 启动服务->登录测试
mongo
show dbs # 默认看不到数据库
# 认证身份
方法1 mongo 服务器IP地址:端口/数据库 -u 用户名 -p 密码
方法2 a-先登录 b-选择数据库 c-输入db.auth(用户名,密码)
练习
添加用户shop1可以读shop数据库
# 注意 选择数据库 用户属于数据库
use shop
## shop1
db.createUser({
'user': 'shop1',
'pwd': 'admin888',
'roles': [{
role: 'read',
db: 'shop'
}]
})
## shop2
db.createUser({
'user': 'shop2',
'pwd': 'admin888',
'rolse': [{
role: 'readWriter',
db: 'shop'
}]
})
验证
mongo localhost:27017/shop -u shop1 -p admin888 #可读不可写
db.goods.find() # 正确执行
db.goods.insert({name: 'zhangsan'}) # 报错
# -------------------------------------------------------
mongo localhost:27017/shop -u shop1 -p admin888 #可读可写
db.goods.find() # 正确执行
db.goods.insert({name: 'zhangsan'}) # 正确执行
语法
导出数据库语法:mongodump -h -port -u -p -d -o
导出语法说明
-h host 服务器ip地址 (一般不写 默认本机
-port 端口(一般不写 默认27017
-u user 账号
-p pwd 密码
-d database 数据库 (注意:不写导出全部
-o open 备份到指定目录下
练习(备份所有数据):mongodump -u admin -p admin888 -o d:\bak
练习(备份指定数据):mongodump -u admin -p admin888 -d test -o d:\bak2
语法
导入数据库语法:mongorestore -h -port -u -p -d --drop 备份数据目录
导入数据库说明
-h host 服务器ip地址 (一般不写 默认本机
-port 端口(一般不写 默认27017
-u user 账号
-p pwd 密码
-d database 数据库 (注意:不写还原全部
--drop 先删除数据库再导入,不写则覆盖
练习(还原所有数据):mongorestore -u admin -p admin888 --drop d:\bak
练习(还原指定数据):mongorestore -u admin -p admin888 -d test --drop d:\bak2\test
订单模块
/order get
/order post
/order/编号 put
/order/编号 delete
导入配置文件
//保证版本相同
<dependency>
<groupId>org.mongodbgroupId>
<artifactId>mongodb-driverartifactId>
<version>3.12.7version>
dependency>
<dependency>
<groupId>org.mongodbgroupId>
<artifactId>mongodb-driver-coreartifactId>
<version>3.12.7version>
dependency>
java代码–查询
//创建连接
MongoClient client = new MongoClient("127.0.0.1",27017);
//获取操作的数据库
MongoDatabase database = client.getDatabase("test");
//获取集合
MongoCollection<Document> collection = database.getCollection("user");
//按照条件进行查询
//第一种
/*Map map = new HashMap();
map.put("name","zhangsan");*/
//BasicDBObject bson = new BasicDBObject("name","zhangsan");
//BasicDBObject bson = new BasicDBObject(map);
//第二种 不能支持多个条件传入
Bson bson = Filters.eq("name", "zhangsan");
//获取文档
FindIterable<Document> iterable = collection.find(bson);
//循环获取内容
for (Document document : iterable) {
System.out.println(document.getString("name"));
}
//关闭连接
client.close();
新增
//创建连接
MongoClient client = new MongoClient("127.0.0.1",27017);
//获取操作的数据库
MongoDatabase database = client.getDatabase("test");
//获取集合
MongoCollection<Document> collection = database.getCollection("user");
Map<String, Object> map = new HashMap<String, Object>();
map.put("name","wangwu");
map.put("sex","男");
map.put("age",25);
Document document = new Document(map);
//插入数据
collection.insertOne(document);
//关闭连接
client.close();
删除
//创建连接
MongoClient client = new MongoClient("127.0.0.1",27017);
//获取操作的数据库
MongoDatabase database = client.getDatabase("test");
//获取集合
MongoCollection<Document> collection = database.getCollection("user");
//一次就删除一条
Bson bson = Filters.eq("name", "wangwu");
collection.deleteOne(bson);
System.out.println("删除成功");
//关闭连接
client.close();
更新
//创建连接
MongoClient client = new MongoClient("127.0.0.1",27017);
//获取操作的数据库
MongoDatabase database = client.getDatabase("test");
//获取集合
MongoCollection<Document> collection = database.getCollection("user");
//更新数据
Bson bson = Filters.eq("name", "zhangsan");
Document document = new Document("$set",new Document("age",23));
collection.updateOne(bson,document);
System.out.println("更新成功");
//关闭连接
client.close();
导入依赖
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-data-mongodbartifactId>
dependency>
配置yml
spring:
data:
mongodb:
host: 127.0.0.1
database: test
实体类
@Data
@NoArgsConstructor
@AllArgsConstructor
@Document(collation = "user")
public class Person {
@Id
private String id;
@Field("name")
private String name;
@Field("sex")
private String sex;
@Field("age")
private Integer age;
}
核心代码
@Autowired
private MongoTemplate mongoTemplate;
@Override
public void save(Person person) {
mongoTemplate.save(person);
}
@Override
public void update(Person person) {
//条件
Query query = new Query(Criteria.where("id").is(person.getId()));
//内容
Update update = new Update();
update.set("age",35);
update.set("sex","女");
mongoTemplate.updateFirst(query,update,Person.class);
}
@Override
public List<Person> findAll() {
return mongoTemplate.findAll(Person.class);
}
@Override
public void delete(String id) {
Person person = mongoTemplate.findById(id, Person.class);
mongoTemplate.remove(person);
}