0.序章
致命的面試問題:為什么使用MongoDB?
大型的分布式的文檔型數據庫,也是NoSQL數據庫(例如 redis)
MongoDB適合數據量大而價值又低的這種數據(播放進度、評論、彈幕,實時數據的CRUD)
因為數據量大,所以不適合用redis,因為redis內存沒這么大;
因為價值低,量又大,所以不適合存儲在MySQL中;
1.MongoDB的相關概念
常識性的內容(類比MySQL學習):
MongoDB:? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??MySQL:
database 數據庫? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ????????????????? database數據庫
collection 集合(建議結構一樣) ????????????????????????table表(數據結構必須相同)
Document文檔(json BSON Binarry-Json)???????row行
field字段 ??????????????????????????????????????????????????????????????column列
_id 主鍵 ???????????????????????????????????????????????????????????????id主鍵
一個數據庫可以有多個集合,一個集合可以保存多條Document。
2.安裝過程(在docker環境中):
mkdir -p /opt/mongo/data/dbdocker load < /opt/mongo.tardocker run -d --restart=always -p 27017:27017 --name mongodb -v /opt/mongo/data/db:/data/db mongo:8.0-rc
3.命令行
數據庫(database)
# 查看數據庫
show dbs# 切換或者新增庫(懶加載,當數據庫中有集合或者數據時,才會真實創建)
use {dbName}# 刪除庫
db.dropDatabase()
集合(collection)
# 創建集合(不是必須操作,操作數據時如果集合不存在則自動創建)
db.createCollection("colName")# 查看集合
show collections# 刪除集合
db.{colName}.drop()
文檔(Document)
# 新增 insert(過期) save(移除) insertOne insertMany
db.{colName}.insertOne({k1:v1,k2:v2})
db.{colName}.insertMany([{k1:v1,k2:v2}, {k1:v1,k2:v2}, {k1:v1,k2:v2}])# 查詢所有
db.{colName}.find()# 基本查詢:等值
db.{colName}.find({k: v, k: v})# 不等值查詢:like($regex) >($gt) <($lt) >=($gte) <=($lte) !=(ne)
db.{colname}.find({k: {$regex: v}})
db.{colName}.find({k: /v/})# or查詢:或者關系
db.{colName}.find({$or: [{k: v}, {k: v}]})# 排序
db.{colName}.find().sort({key: 1/-1})# 分頁
db.{colName}.find().skip((pageNum-1))*pageSize).limit(pageSize)# 更新
db.{colName}.updateOne({查詢條件}, {$set: {k: v, k: v}})# 刪除
db.{colName}.deleteOne({k: v})
db.{colName}.deleteMany({k: v})
db.{colName}.deleteMany({})
4.Java客戶端
UI客戶端
官方提供的GUI客戶端:MongoDB Compass
Java客戶端
SpringData-MongoDB
引入依賴:
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
配置:
# mongodb的配置
spring.data.mongodb.uri=mongodb://ip:port/dbNamespring.data.mongodb.host=192.168.30.100
spring.data.mongodb.port=27017
spring.data.mongodb.database=demo
代碼:
@SpringBootTest
public class MongoTest {@Autowiredprivate MongoTemplate mongoTemplate;@Testvoid test(){this.mongoTemplate.createCollection("collection1");}
}
實際操作過程:
-
引入依賴
-
配置
-
編寫實體類:pojo類
@Document:作用在類上,標記對應的MongoDB的集合名稱
@Id:作用在主鍵字段上,建議一定要有一個字段聲明為id,_id
@Field:可以省略,除非字段名不一致
@Document("user")
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {@Id // 建議一定要有一個字段定義為id,對應到_idLong id;@Field("username") // 該注解可以省略,如果字段名和MongoDB中字段名不一致,才需要指定String name;Integer age;Boolean gender;String pwd;
}
4.mongoTemplate實現文檔的CRUD:數據庫和集合都可以不用顯式創建
// 新增一個 批量新增@Testvoid testInsert(){this.mongoTemplate.insert(new User(1L, "柳巖", 20, false, "123456"));}// 更新@Testvoid testUpdate(){
// UpdateResult result = this.mongoTemplate.updateFirst(UpdateResult result = this.mongoTemplate.updateMulti(
// Query.query(Criteria.where("age").gte(33)),Query.query(Criteria.where("name").regex("小")),Update.update("age", 30),User.class);System.out.println(result.getMatchedCount());System.out.println(result.getModifiedCount());}// 刪除@Testvoid testDelete(){DeleteResult result = this.mongoTemplate.remove(Query.query(Criteria.where("age").lte(23)), User.class);System.out.println(result.getDeletedCount());}
5.查詢條件:
this.mongoTemplate.find(Query對象)
Query對象的初始化:Query.query(Criteria)
Criteria對象的初始化:Criteria.where("key").is/gt/gte/lt/lte/ne/regex("value").and("key1").is("value1")
排序:Query.query().with(Sort.by(Order.asc/desc("key")))
分頁:Query.query().skip((pageNum-1)*pageSize).limit(pageSize)
this.mongoTemplate.find(Query.query(Criteria.where("age").lte(30)
// .andOperator(Criteria.where("age").lte(34)) // 同一個字段使用多次,需要andOperator.and("name").regex("小") // 如果是不同字段,一直向后進行and操作.and("pwd").is("123456").orOperator(Criteria.where("name").regex("小")) // 得出的交集不是并集。), User.class).forEach(System.out::println);// 排序this.mongoTemplate.find(Query.query(Criteria.where("name").regex("小")).with(Sort.by(Sort.Order.asc("age"))).skip(8).limit(4).with(PageRequest.of(2, 4)) // 頁碼從0開始, User.class).forEach(System.out::println);