1.什么是mongodb
一个文档数据库,以JSON为数据模型,由C++语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。
- Database(库):类似于 MySQL 数据库的概念,用来隔离不同的应用数据,不同数据库存放在不同的文件中。默认的数据库为 test.
- Collection(集合):类似于 MySQL 中表的概念,一个库中可以创建多个集合,并且每个集合不像 MySQL 表有固定的结构,这也意味着对集合可以插入不同格式类型的数据. 但通常情况下我们插入集合的数据都有一定的关联性.
- Document(文档):类似于 MySQL 中表中的一条数据. 文档集合中的一条条记录,是一组 BSON 类型的键值对。MongoDB 文档最大的特点就是每个文档之间可以使用不同的字段和数据类型。
2.数据库操作
查看所有库:show dbs
切换库,不存在则创建:use 表名
查看当前操作库:db
删除当前数据库:db.dropDatabase()
3.集合操作
MongoDB中的集合是一组文档的集,相当于关系型数据库中的表。
查看集合:show collections
删除集合:db.集合名.drop()
创建集合:db.createCollection('集合名',[option])
options 可以是可选参数,如下:
capped:布尔类型. 如果为 true,则创建固定集合(有固定大小的集合,当集合到达最大值时,会自动覆盖最早的文档. 如果值为 true,必须指定 size 参数)
size:数值类型. 指定集合最大值,单位字节. 如果 capped 为 true ,也需要指定该字段.
max:数值类型. 指定固定集合中文档的最大数量
db.createCollection('Users',{max:100,capped:true});
4.文档操作
4.1 插入文档
插入单条文档:db.集合名.insertOne({"key 1:"value 1","key N","value N"})
插入多条文档:db.集合名.insertMany([{"key 1":"value 1","key 2","value 2"},{"key 3":"value 3","key 4","value 4"}])
同时insertOne和insertMany支持writeConcern
db.Users.insertMany([{"name":"张三","age","18"},{"name":"李四","age","24"}])
4.2 文档查询
查询文档:db.集合名.find(query, projection)
query:可选,使用查询操作符指定查询条件.
projection:可选,使用投影操作符指定返回的键。查询时返回文档中所有键值,只需要省略该参数即可(默认省略).
1
表示包含该字段。0
表示排除该字段。-
db.collection.find({}, { _id: 0, name: 1, email: 1 })
按照条件查询
findOne默认会返回第一条
db.Users.find({name: "王五"})
db.Users.findOne({name: "王五"})
按照表自带id进行查询
db.Users.find({_id:ObjectId("213e1241a24161e23")})
多条件涉及大小于比对的查询
age>20 --> age:{$gt:20}
db.Users.find({type:"student",age:{$gt:20}})
查询条件对照表
AND连接
db.集合名.find(query,query)
db.Users.find({age: 15, name: "syx"});
OR连接
db.集合名.find({$or: [query,query]})
db.Users.find({$or: [{name: "syx"}, {name: "SYX"}]})
Like模糊查询
db.集合名.find({字段名:/查询词/})
db.Users.find({name: /苏/})
4.3 排序及分页
排序:db.集合名.find(query,projection).sort({字段名:排序方式})
排序方式 1升序,-1降序
分页:db.集合名.find(query,projection).skip(跳过数).limit(限制数)
skip为跳过n条数据,limit为限制显示n条数据
db.Users.find().skip(0).limit(3);
4.4 更新文档
db.集合名.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 表示不插入.
multit(可选):默认是 false,只更新找到的第一条记录,如果这个参数为 true,就把按条件查出来的多条记录全部更新.
writeConcernt(可选):抛出异常的级别.
示例一:将符合条件的全部更新成后面的文档,相当于先删除再插入(不保留原有文档).
db.Users.update({name: "syx"}, {name: "suyunxiang", bir: new Date()})
示例二:更新是所有符合条件的数据,并且保留原有数据,只更新指定字段. => $set
db.Users.update({name: "suyunxiang"}, {$set: {name: "syx"}},{multi: true})
示例三:更新符合条件的所有数据,保留原有数据,只更新指定字段. 如果没有条件符合时,直接插入数据.
db.Users.update({name: "xys"}, {$set: {name: "suyunxiang"}}, {multi:true, upsert:true});
5.SpringBoot整合mongodb配置
Maven依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
配置文件(详情参考文档):
spring:
data:
mongodb:
uri: mongodb://192.168.73.3:27017/demo
# mongodb://host地址:port端口/库名
username: root
password: 1234
使用时需要注入mongodbTemplate
6.springboot操作集合
6.1创建集合
@Autowired
private MongoTemplate mongoTemplate;
public void createCollection() {
if(!mongoTemplate.collectionExists("demo")) {
//不存在才能创建,如果以及存在再创建就会报错
mongoTemplate.createCollection("demo");
}
}
6.2删除集合
mongoTemplate.dropCollection("demo");
7.springboot操作文档
7.1 声明文档对应实体类
@Document
修饰范围:在类上.
作用:映射当前类的一个对象为 mongo 的一条文档.
属性:value 和 collection 都是用来表示操作的集合名.
@Id
修饰范围:成员变量、方法.
作用:将值映射成文档的 _id.
@Field
修饰范围:成员变量、方法.
作用:将值映射为文档中的一个 key 名称.
@Transient
修饰范围:成员变量、方法.
租用:指定值不参与文档序列化.
@Data
@AllArgsConstructor
@NoArgsConstructor
@Document("demo")
public class User {
@Id
private String userId;
@Field("username")
private String name;
@Field
private String email;
@Field
private String password;
@Transient
private String userNo;
}
7.2 新增文档
Save:出现重复会覆盖,但是只支持单个新增
void save (Object objectToSave) 保存文档到默认的集合。
void save(Object objectToSave, String collectionName) 对指定的集合进行保存。
Insert:出现重复会报异常,但是支持批量新增
void insert(Object objectToSave) 保存文档到默认的集合。
void insert(Object objectToSave, String collectionName) 对指定的集合进行保存。
@Autowired
private MongoTemplate mongoTemplate;
@Test
void contextLoads() {
//单个新增
User user = new User("u1","苏云翔","123456@qq.com","Aa123456@","1");
mongoTemplate.insert(user);
//insert存在会报异常,save会更新,但是insert支持批量新增
//mongoTemplate.save(user);
//批量新增
List<User> users = Arrays.asList(
new User("u2","王二","1111111@qq.com","A142345","2"),
new User("u3","张三","2222222@qq.com","Aa122316#","3")
);
mongoTemplate.insert(users,User.class);
}
7.3 查询文档
7.3.1 查询所有文档
public <T> java.util.List<T> findAll(java.lang.Class<T> entityClass
List<User> list = mongoTemplate.findAll(User.class);
7.3.2 根据id查询
public <T> T findById(java.lang.Object id, java.lang.Class<T> entityClass)
String userId = "H8126A7321";
User user = mongoTemplate.findById(userId,User.class);
7.3.3 条件查询文档
条件符说明
例:
public class UserRepository {
private final MongoTemplate mongoTemplate;
private static final String COLLECTION_NAME = "users";
public UserRepository(MongoTemplate mongoTemplate) {
this.mongoTemplate = mongoTemplate;
}
/**
* 指定field查询
*/
public void specialFieldQuery() {
Query query = new Query(Criteria.where("user").is("用户名blog"));
// 查询一条满足条件的数据
User result = mongoTemplate.findOne(query, User.class, COLLECTION_NAME);
System.out.println("query: " + query + " | specialFieldQueryOne: " + result);
// 满足所有条件的数据
List<User> ans = mongoTemplate.find(query, User.class, COLLECTION_NAME);
System.out.println("query: " + query + " | specialFieldQueryAll: " + ans);
}
/**
* 多个查询条件同时满足
*/
public void andQuery() {
Query query = new Query(Criteria.where("user").is("用户名blog").and("age").is(18));
User result = mongoTemplate.findOne(query, User.class, COLLECTION_NAME);
System.out.println("query: " + query + " | andQuery: " + result);
}
/**
* 或查询
*/
public void orQuery() {
// 等同于 db.getCollection('users').find({"user": "用户名blog", $or: [{ "age": 18}, { "sign": {$exists: true}}]})
Query query = new Query(Criteria.where("user").is("用户名blog")
.orOperator(Criteria.where("age").is(18), Criteria.where("sign").exists(true)));
List<User> result = mongoTemplate.find(query, User.class, COLLECTION_NAME);
System.out.println("query: " + query + " | orQuery: " + result);
// 单独的or查询
// 等同于Query: { "$or" : [{ "age" : 18 }, { "sign" : { "$exists" : true } }] }, Fields: { }, Sort: { }
query = new Query(new Criteria().orOperator(Criteria.where("age").is(18), Criteria.where("sign").exists(true)));
result = mongoTemplate.find(query, User.class, COLLECTION_NAME);
System.out.println("query: " + query + " | orQuery: " + result);
}
/**
* in查询
*/
public void inQuery() {
// 相当于:
Query query = new Query(Criteria.where("age").in(Arrays.asList(18, 20, 30)));
List<User> result = mongoTemplate.find(query, User.class, COLLECTION_NAME);
System.out.println("query: " + query + " | inQuery: " + result);
}
/**
* 数字类型,比较查询 >
*/
public void compareBigQuery() {
// age > 18
Query query = new Query(Criteria.where("age").gt(18));
List<User> result = mongoTemplate.find(query, User.class, COLLECTION_NAME);
System.out.println("query: " + query + " | compareBigQuery: " + result);
// age >= 18
query = new Query(Criteria.where("age").gte(18));
result = mongoTemplate.find(query, User.class, COLLECTION_NAME);
System.out.println("query: " + query + " | compareBigQuery: " + result);
}
/**
* 数字类型,比较查询 <
*/
public void compareSmallQuery() {
// age < 20
Query query = new Query(Criteria.where("age").lt(20));
List<User> result = mongoTemplate.find(query, User.class, COLLECTION_NAME);
System.out.println("query: " + query + " | compareSmallQuery: " + result);
// age <= 20
query = new Query(Criteria.where("age").lte(20));
result = mongoTemplate.find(query, User.class, COLLECTION_NAME);
System.out.println("query: " + query + " | compareSmallQuery: " + result);
}
/**
* 正则查询
*/
public void regexQuery() {
Query query = new Query(Criteria.where("user").regex("^用户名blog"));
List<User> result = mongoTemplate.find(query, User.class, COLLECTION_NAME);
System.out.println("query: " + query + " | regexQuery: " + result);
}
/**
* 查询总数
*/
public void countQuery() {
Query query = new Query(Criteria.where("user").is("用户名blog"));
long cnt = mongoTemplate.count(query, User.class, COLLECTION_NAME);
System.out.println("query: " + query + " | cnt " + cnt);
}
/**
* 排序查询
*/
public void sortQuery() {
// sort查询条件,需要用with来衔接
Query query = Query.query(Criteria.where("user").is("用户名blog")).with(Sort.by("age"));
List<User> result = mongoTemplate.find(query, User.class, COLLECTION_NAME);
System.out.println("query: " + query + " | sortQuery " + result);
}
/**
* 分页查询
*/
public void pageQuery() {
// limit限定查询2条
Query query = Query.query(Criteria.where("user").is("用户名blog")).with(Sort.by("age")).limit(2);
List<User> result = mongoTemplate.find(query, User.class, COLLECTION_NAME);
System.out.println("query: " + query + " | limitPageQuery " + result);
// skip()方法来跳过指定数量的数据
query = Query.query(Criteria.where("user").is("用户名blog")).with(Sort.by("age")).skip(2);
result = mongoTemplate.find(query, User.class, COLLECTION_NAME);
System.out.println("query: " + query + " | skipPageQuery " + result);
}
}
7.4 更新文档
updateFirst()只更新满足条件的第一条记录
updateMulti()更新所有满足条件的记录
upsert()没有符合的则进行插入
Query query = new Query(Criteria.where("name").is("syx"));
Update update = new Update();
update.set("age",20);
UpdateResult updateResult = mongoTemplate.updateFirst(query,update,User.class);
7.5 删除文档
//为指定条件则全部删除
mongoTemplate.remove(new Query(),User.class);
//条件删除
Query query = new Query(Criteria.where("name").is("syx"));
mongoTemplate.remove(query,User.class);