MongoDB的CURD操作
插入文档
版本之后新增了 db.collection.insertOne() 和 db.collection.insertMany()。
db.collection.insertOne() 用于向集合插入一个新文档,语法格式如下:
db.collection.insertOne(
<document>,
{
writeConcern: <document>
}
)
db.collection.insertMany() 用于向集合插入一个多个文档,语法格式如下:
db.collection.insertMany(
[ <document 1> , <document 2>, ... ],
{
writeConcern: <document>,
ordered: <boolean>
}
)
参数说明:
- document:要写入的文档。
- writeConcern:写入策略,默认为 1,即要求确认写操作,0 是不要求。
- ordered:指定是否按顺序写入,默认 true,按顺序写入。
操作
/**
新增一条数据,单个插入
当我们向集合中插入文档时,
如果没有给文档指定_id属性,
则数据库会自动为文档添加_id
该属性用来作为文档的唯一标识
*/
db.student.insert({names:"张三",age:17,sex:"男"})
//新增一条数据以数组的形式插入
db.student.insert([
{names:"李四",age:17,sex:"男"},
{names:"王五",age:17,sex:"女"}
])
//或者
//插入单条数据
db.student.insertOne({
names:"王起",age:17,sex:"女"
})
//插入多条数据
db.student.insertMany(
[
{names:"老八",age:17,sex:"男"},
{names:"老刘",age:17,sex:"女"}
]
)
//生成一个唯一ID
//ObjectId()
//查询全部数据
db.student.find()
查询文档
MongoDB 查询文档使用 find() 方法。
find() 方法以非结构化的方式来显示所有文档。
语法
MongoDB 查询数据的语法格式如下:
db.collection.find(query, projection)
- query :可选,使用查询操作符指定查询条件
- projection :可选,使用投影操作符指定返回的键。查询时返回文档中所有键值, 只需省略该参数即可(默认省略)。
如果你需要以易读的方式来读取数据,可以使用 pretty() 方法,语法格式如下:
>db.col.find().pretty()
pretty() 方法以格式化的方式来显示所有文档。
操作
//查询全部数据
db.student.find()
//查询文档操作,带条件查询
db.student.find({names:"老八"}).pretty()
db.student.find({names:"老八",age:17}).pretty()
//只查询符合条件中的第一个
db.student.findOne({names:"老八"})
//查询结果的数量
db.student.find({}).count()
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 |
操作
//查询大于16小于80的
db.student.find({age:{$gt:16,$lt:80}})
//查询名称不等于张三的
db.student.find({names:{$ne:"张三"}})
//查询名字等于老刘的
db.student.find({names:"老刘"})
//查询大于等于17小于20的
db.student.find({age:{$gte:17,$lte:20}})
MongoDB and和or条件
and语法:
db.col.find({key1:value1, key2:value2}).pretty()
or语法
>db.col.find(
{
$or: [
{key1: value1}, {key2:value2}
]
}
).pretty()
操作
//查询姓名为张三或者性别为女的
db.student.find({$or:[{names:"张三"},{sex:"女"}]})
//查询姓名为张三并且性别为男的
db.student.find({names:"张三"},{age:"男"})
//where likes>16 AND (names = '张三' OR names = '李四')'
db.student.find({age:{$gt:16}, $or: [{"names": "张三"},{"names": "李四"}]})
修改文档
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 :可选,抛出异常的级别。
//修id为62430377fe040000ad0017ed名字为李四,年龄为30,修改一个,找到的第一个参数
db.student.update({"_id":ObjectId("62430377fe040000ad0017ed")},
{
$set:{
names:"李四",
age:"30"
}
})
//修改多个参数年龄为40
db.student.updateMany({"names":"老八"},
{
$set:{
age:"40"
}
})
//也可以设置 multi:true来修改多个值
db.student.update({"names":"老八"},
{
$set:{
age:"25"
}
},
{
multi:true
})
//修改单个updateOne修改单个值,修改找到的第一个参数
db.student.updateOne({"names":"老八"},
{
$set:{
age:100
}
})
删除文档
ongoDB remove() 函数是用来移除集合中的数据。
MongoDB 数据更新可以使用 update() 函数。在执行 remove() 函数前先执行 find() 命令来判断执行的条件是否正确,这是一个比较好的习惯。
语法
remove() 方法的基本语法格式如下所示:
db.collection.remove(
<query>,
<justOne>
)
如果你的 MongoDB 是 2.6 版本以后的,语法格式如下:
db.collection.remove(
<query>,
{
justOne: <boolean>,
writeConcern: <document>
}
)
参数说明:
- query :(可选)删除的文档的条件。
- justOne : (可选)如果设为 true 或 1,则只删除一个文档,如果不设置该参数,或使用默认值 false,则删除所有匹配条件的文档。
- writeConcern :(可选)抛出异常的级别。
操作
//删除年龄为100的,只删除一条
db.student.deleteOne({age:100});
//删除多条数据,删除名称为老八的
db.student.deleteMany({names:"老八"})
//删除名字为王起的,默认删除多条
db.student.remove({names:"王起"})
//删除名字为李四的,设置为true删除一条
db.student.remove({names:"李四"},true)
//清空集合(性能较差)
db.student.remove({})
//删除集合
db.student.drop()
//删除数据库
db.dropDatabase()
CURD练习操作
基本练习一
//向数据的user集合中插入以文档
db.users.insert({names:"张三",age:18})
//插入user集合中的文档
db.users.find()
//统计user集合中文档的数量
db.users.find().count();
//查询user集合中名字为张三的文档
db.users.find({names:"张三"})
//向数据库user集合中的name为张三的文档,添加一个address属性,属值为北京
db.users.update({names:"张三"},{$set:{address:"北京"}})
//将张三的名字改为李四
db.users.replaceOne({names:"张三"},{names:"李四",address:"北京"})
//删除user文档中名字为李四的address属性
db.users.update({names:"李四"},{$unset:{address:1}})
//向user文档中名称为李四的人添加一个hobby:{cities:["北京","上海","深圳"]}
//MongoDB的文档的属性值也可以是一个文档,当一个文档的属性值是一个文档时,我们称这个文档叫做内嵌文档
db.users.update({names:"李四"},{$set:{hobby:{cities:["北京","上海","深圳"]}}})
//向user文档中名为李四的添加一个hobby:{movies:["三国演义","西游记","红楼梦","水浒传"]}
db.users.update({names:"李四"},{$set:{hobby:{movies:["三国演义","西游记","红楼梦","水浒传"]}}})
//查询喜欢电影三国演义的文档
//MongoDB支持直接通过内嵌文档的属性进行查询,
//如果要查询内嵌文档则可以通过。的形式来匹配如果要通过内嵌文档来对文档进行查询,此时属性名必须使用引号
db.users.find({'hobby.movies':"三国演义"})
//向李四喜欢的电影中添加一个元素为大闹天宫
//$push:给文档添加一个值
//$addToset向数组中添加一个新元素,如果数组中已经存在了该元素,则不会添加
db.users.update({names:"李四"},{$push:{'hobby.movies':"大闹天宫"}})
db.users.update({names:"李四"},{$push:{'hobby.movies':"伪装者"}})
//删除喜欢西游记的用户
db.users.remove({"hobby.movies":"西游记"})
//删除user集合
db.users.remove({})
db.users.drop()
show dbs
//向numbers插入2000条数据
//效率低下
for (var i=1;i<=2000;i++){
db.numbers.insert({num:i})
}
db.numbers.find().count()
db.numbers.remove({})
//效率高效
var arr=[];
for (var i = 0; i <2000; i++) {
arr.push({num:i});
}
db.numbers.insert(arr)
db.numbers.find().count()
练习2
//查询numbers中num为500的文档
db.numbers.find({num:500})
db.numbers.find({num:{$eq:500}})
//查询numbers中num大于1500的文档
db.numbers.find({num:{$gt:1500}})
//查询numbers中num小于30的文档
db.numbers.find({num:{$lt:30}})
//查询numbers中num大于40小于50的文档
db.numbers.find({num:{$gt:40,$lt:50}})
//查询numbers中的num大于1996的文档
db.numbers.find({num:{$gt:1996}})
//查询前10条数据
db.numbers.find().limit(10)
//查询10条到20条的数据
//skip:从多少条狂神查
//limit:查询的条数
db.numbers.find().skip(10).(10)
//查询学生表前5条数据以降序的方式排列 sort({age:1}):改为一升序
db.student.find().skip(0).limit(5).sort({age:-1})
//查询指定的字段,1:代表显示,0:代表不显示
db.student.find({},{names:1,_id:0})
关联查询
/**
一对一(one to one)
一对多(one to many)
多对一(many to one)
多对多(many to many)
*/
//一对一
db.wife.insert([
{
names:"老八",
husband:{
names:"小汉堡"
}
},{
names:"唐冯浩",
husband:{
names:"螳粪号"
}
}
])
db.wife.find()
//一对多
db.users.insert([
{username:"张三"},
{username:"李四"}
])
db.users.find()
db.order.insert({
list:["香蕉","苹果","李子"],
user_id:ObjectId("62455cd0310e00009c007704")//指定张三的_Id
})
//查找张三的订单,一起执行
var user_Id=db.users.findOne({username:"张三"})._id
db.order.find({user_id:user_Id})
//多对多
db.teachers.insert([
{names:"彭懿航"},
{names:"唐冯浩"},
{names:"唐老八"}
]);
db.teachers.find()
db.stus.insert([
{
names:"小黑",
tech_ids:[
ObjectId("62455f6f310e00009c007707"),
ObjectId("62455f6f310e00009c007708")//指定老师的_id
]
},
{
names:"小白",
tech_ids:[
ObjectId("62455f6f310e00009c007707"),
ObjectId("62455f6f310e00009c007709"),
ObjectId("62455f6f310e00009c007708")//指定老师的_id
]
}
])
db.stus.find()
使用MongoDB整合SpringBoot实现CURD
环境准备
官网:https://www.mongodb.com/docs/manual/reference/connection-string/
导入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
application.yml
spring:
data:
mongodb:
uri: mongodb://localhost:27017/student
#uri 等同与一下配置
# database: student
# host: localhost
# username: fox
# password: fox
# authentication-database: admin
测试类
@SpringBootTest
class MongodbApplicationTests {
@Autowired
MongoTemplate mongoTemplate;
/**
* 集合操作
*/
@Test
void contextLoads() {
//判断集合是否存在
boolean exists = mongoTemplate.collectionExists("emp");
if (exists) {
//删除集合
mongoTemplate.dropCollection("emp");
}
//创建集合
mongoTemplate.createCollection("emp");
}
}
添加文档操作
相关注解
@Document
修饰范围:用在类上
作用:用来映射这个类的一个对象为mongo中一条文档数据
属性:( value , collection )用来指定操作的集合名称
@ld
修饰范围:用在成员变量、方法上
作用:用来将成员变量的值映射为文档的_id的值.
@Field
修饰范围:用在成员变量、方法上
作用:用来将成员变量及其值映射为文档中一个key:value对。
属性:(name , value )用来指定在文档中key的名称,默认为成员变量名.
@Transient
修饰范围:用在成员变量、方法上
作用:用来指定此成员变量不参与文档的序列化
实体类
package com.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 org.springframework.data.mongodb.core.mapping.Field;
import java.util.Date;
@Document("emp") //对应emp集合中的一个文档
@AllArgsConstructor
@NoArgsConstructor
@Data
public class Employee {
@Id //映射文档的_id
private Integer id;
@Field("name")
private String name;
@Field
private Double salary;
@Field
private Date birthday;
}
测试类
/**
* 添加员工
*/
@Test
void testInsert() {
// Employee employee = new Employee(1,"小黑",3000.00,new Date());
// mongoTemplate.insert(employee);
//或者
//mongoTemplate.save(employee);
//插入多条数据
List<Employee> list= Arrays.asList(
new Employee(2,"张三",3000.00,new Date()),
new Employee(3,"李四",3000.00,new Date()),
new Employee(4,"王五",3000.00,new Date())
);
mongoTemplate.insert(list,Employee.class);
}
查询文档操作
测试类
//查询所有文档
System.out.println("=====查询所有文档=====");
List<Employee> all = mongoTemplate.findAll(Employee.class);
all.forEach(System.out ::println);
System.out.println("=====根据id查询=====");
Employee byId = mongoTemplate.findById(1, Employee.class);
System.out.println(byId);
System.out.println("====查询返回结果的第一个文档====");
Employee one = mongoTemplate.findOne(new Query(), Employee.class);
//如果查询的是多个,返回的是第一个文档
System.out.println(one);
System.out.println("=====条件查询=====");
new Query();//表示没有条件
//查询大于等于5000的员工,salary:数据库的字段
Query salary = new Query(Criteria.where("salary").gte(5000));
List<Employee> list = mongoTemplate.find(salary, Employee.class);
list.forEach(System.out::println);
//查询大于3000小于5000的
Query salary1 = new Query(Criteria.where("salary").gt(3000).lt(5000));
List<Employee> list1 = mongoTemplate.find(salary1, Employee.class);
list1.forEach(System.out::println);
//正则查询(模糊查询)
Query query = new Query(Criteria.where("name").regex("张"));
List<Employee> list2 = mongoTemplate.find(query, Employee.class);
list2.forEach(System.out::println);
System.out.println("====多条件查询 and or====");
Criteria criteria = new Criteria();
//and查询名字的张三薪资大于3000的员工
criteria.andOperator(Criteria.where("name").is("张三"),Criteria.where("salary").gt(3000));
Query query1 = new Query(criteria);
List<Employee> list3 = mongoTemplate.find(query1, Employee.class);
list3.forEach(System.out::println);
//or查询姓名是张三或者薪资大于5000的员工
Criteria criteria1 = criteria.orOperator(Criteria.where("name").is("张三"), Criteria.where("salary").gt(5000));
Query query2 = new Query(criteria1);
List<Employee> list4 = mongoTemplate.find(query2, Employee.class);
list4.forEach(System.out::println);
System.out.println("=======排序=======");
//排序
Query pai = new Query();
pai.with(Sort.by(Sort.Order.desc("salary")));
List<Employee> sort = mongoTemplate.find(pai, Employee.class);
sort.forEach(System.out::println);
System.out.println("======分页=====");
Query fen = new Query();
fen.with(Sort.by(Sort.Order.desc("salary")))
.skip(0)//起始页
.limit(2);//指定的条数
List<Employee> limit = mongoTemplate.find(fen, Employee.class);
limit.forEach(System.out::println);
使用JSON进行查询
/**
* 使用josn进行查询
*/
@Test
void jsonTest(){
//等值查询
//String josn="{name:'张三'}";
//多条件查询
String Json="{$or:[{name:'张三'},{salary:{$gte:4000}}]}";
BasicQuery basicQuery = new BasicQuery(Json);
List<Employee> list = mongoTemplate.find(basicQuery, Employee.class);
list.forEach(System.out ::println);
}
更新文档操作
在Mongodb中无论是使用客户端API还是使用Spring Data,更新返回结果一定是受行数影响。如果更新后的结果和更新前的结果是相同,返回0。
updateFirst()只更新满足条件的第一条记录.
updateMulti()更新所有满足条件的记录.
upsert()没有符合条件的记录则插入数据
实例
/**
* 修改
*/
@Test
void updateTest(){
//修改条件大于等于5000的
Query query=new Query(Criteria.where("salary").gte(8000));
Update update = new Update();
//设置更新属性
update.set("salary",100000);
//updateFirst,只更新满足条件的第一条数据
//UpdateResult updateResult = mongoTemplate.updateFirst(query, update, Employee.class);
//updateMulti() 更新满足条件的所有记录
//UpdateResult updateResult1 = mongoTemplate.updateMulti(query, update, Employee.class);
//upsert() 没有该记录,插入数据
update.setOnInsert("id",11);//指定_id
UpdateResult upsert = mongoTemplate.upsert(query, update, Employee.class);
System.out.println("===============>"+upsert.getModifiedCount());
}
删除文档操作
实例
/**
* 删除文档操作
*/
@Test
void deleteTest() {
//删除所有文档
// DeleteResult remove = mongoTemplate.remove(new Query(), Employee.class);
//System.out.println("=================>"+remove.getDeletedCount());
//条件删除
Query query = new Query(Criteria.where("salary").gte(9000));
DeleteResult remove = mongoTemplate.remove(query, Employee.class);
System.out.println("=================>"+remove);
}