MongoDB學習
一, NoSQL簡介
NoSQL(Not Only SQL), 意為 “不僅僅是SQL”
NoSQL指的是非關係型的數據庫. 是對不同於傳統的關係型數據庫的數據庫的關係型的數據庫管理系統的統稱.
CAP定理 :
- 一致性(Consistency) :所有節點在同一時間具有系統的數據
- 可用性(Availability) :保證每個請求不管成功或者失敗都有響應
- 分隔容忍(Partition tolerance) :系統中任意信息的丟失或失敗不會影響系統的繼續運作
CAP理論的核心是: 一個分佈式系統不可能同時很好的滿足一致性, 可用性和分區容錯性這三個需求, 最多只能同時較好的滿足兩個. 因此, 根據CAP原理將NoSQL數據庫分為了滿足CA原則, CP原則和AP原則三大類.
- CA: 單點集群, 滿足一致性, 可用性的系統, 通常在可擴展性上不太強.
- CP: 滿足一致性, 分區容忍性的系統, 通常性能不是特別高.
- AP: 滿足可用性, 分區容忍性的系統, 通常可能對一致性要求低一點.
二, MongoDB介紹
MongoDB是一個面向文檔存儲的數據庫, 操作起來比較簡單和容易.
SQL術語 | MongoDB術語 | 解釋 |
---|---|---|
database | database | 數據庫 |
table | collection | 數據庫表 / 集合 |
row | document | 數據記錄行 / 文檔 |
column | field | 數據字段 / 域 |
index | index | 索引 |
table joins | 表連接, MongoDB不支持 | |
primary key | primary key | 主鍵,MongoDB自動將_id字段設置為主鍵 |
文檔: 文檔是一組鍵值對(即json). 一個簡單的文檔如下所示:
{"name": "lmc", "gender" : "male"}
集合: 集合就是MongoDB文檔組, 類似於RDBMS中的表格. 集合沒有固定的結構, 這意味著可以插入不同格式和類型的數據. 一個簡單的集合如下所示:
{"name": "lmc"}
{"name": "lmchh", "gender" : "male"}
{"name": "sb", "gender" : "female", "age" : 23}
保留數據庫:
數據庫名 | 解釋 |
---|---|
admin | 從權限的角度看, 這是root數據庫. 要是將一個用戶添加到這個數據庫, 這個用戶自動繼承所有數據庫的權限. 一些特定的服務器端命令也只能從這個數據庫運行 |
local | 這個數據永遠不會被複製, 可以用來存儲限於本地單台服務器的任意集合 |
config | 當Mongo用於分片設置時, config數據庫在內部使用, 用於保存分片的相關信息. |
2.1 MongoDB基本命令
命令 | 解釋 |
---|---|
db | 顯示當前數據庫對象或集合 |
show dbs | 顯示所有數據的列表 |
use XXX | 連接到一個指定的數據庫XXX |
show tables 或 show collections | 查看已有集合 |
db.COLLECTION_NAME.find() | 查看該集合的文檔 |
db.repairDatabase()或db.runCommand({repairDatabase:1}) | 回收磁盤空間 |
2.1.1 數據庫
創建數據庫
use DATABASE_NAME
如果數據庫不存在, 則創建數據庫, 否則切換到指定數據庫.
刪除數據庫
db.dropDatabase()
刪除當前數據庫, 默認為 test
2.1.2 集合
創建集合
db.createCollection(COLLECTION_NAEM, OPTION)
參數說明 :
- COLLENTION_NAME: 要創建的集合名稱
- OPTIONS : 可選參數, 指定有關內存大小及索引的選項
在MongoDB中, 不需要創建集合, 當插入一些文檔時, MongoDB會自動創建集合
db.COLLECTION_NAME.insert(...)
自動創建集合 COLLECTION_NAME
刪除集合
db.COLLECTION_NAME.drop()
2.1.3 文檔
插入文檔
MongoDB使用insert()或save()方法向集合中插入文檔
db.COLLECTION_NAME.insert(...)
或
db.COLLECTION_NAME.insertOne(...)
更新文檔
update()方法用於更新已存在的文檔
db.COLLECTION_NAME.update(
<query>,
<update>,
{
upsert: <boolean>,
multi: <boolean>,
writeConcern: <document>
}
)
- query : update的查詢條件, 類似SQL update查詢內where後面內容
- update: update的對象和一些更新的操作符等, 也可以理解為SQL update查詢內set後面內容
- upsert: 可選, 意思是如果不存在update的記錄, 是否插入. true為插入, 默認是false
- multi: 可選, MongoDB默認是false, 只更新找到的第一條記錄, 如果這個參數為true, 就把按條件查出來的多個記錄全部更新.
- writeConcern: 可選, 拋出異常的級別.
簡單示例 :
//先在集合中插入文檔
db.runoob.insertOne({"name":"test",age:12,gender: "male"})
//執行更新操作
db.runoob.update({name:"test"},{$set:{age:18}})
save()方法
save()方法通過傳入的文檔來替換已有文檔, _id主鍵存在就更新, 不存在就插入
刪除文檔
MongoDB remove()函數用來移除集合中的數據, 用法如下:
db.COLLECTION_NAME.remove(
<query>,
{
justOne: <boolean>,
writeConcern: <document>
}
)
query: 可選, 刪除的文檔的條件
justOne: 可選, 如果設為true或1, 則只刪除一個文檔, 如果不設置該參數, 或使用默認值false, 則刪除所有匹配條件的文檔.
//刪除所有name為lmc的數據
db.COLLECTION_NAME.remove({name: "lmc"})
//只刪除一條name為lmc的數據
db.COLLECTION_NAME.remove({name: "lmc"}, 1)
目前官方推薦使用deleteOne()和deleteMany()方法
2.2 查詢
MongoDB查詢文檔使用find()方法
db.COLLECTION_NAME.find(query, projection)
或
db.COLLECTION_NAME.findOne(query, projection)
- query: 可選, 使用查詢操作符指定查詢條件
- projection: 可選, 使用投影操作符指定返回的值. 查詢時返回文檔中所有鍵值, 只需省略該參數即可.
如果需要以易讀的方式來讀取數據, 可以使用pretty()方法. pretty()以格式化的方式來顯示所有文檔.
db.COLLECTION_NAME.find().pretty()
2.2.1 條件操作符
操作 | 操作符 | 格式 |
---|---|---|
等於 | {key : value} | |
小於 | $lt | {key : {$lt : value}} |
小於或等於 | $lte | {key : {$lte : value}} |
大於 | $gt | {key : {$gt : value}} |
大於或等於 | $gte | {key : {$gte : value}} |
不等於 | $ne | {key : {$ne : value}} |
2.2.2 AND條件
AND條件就是傳入多個鍵, 每個鍵以逗號隔開, 即
db.COLLECTION_NAME.find({key1: value1, key2: value2}).pretty()
即
db.COLLECTION_NAME.find(
{
key1: value1,
key2: value2
}
).pretty()
2.2.3 OR條件
MongoDB對or條件語句使用了關鍵字 $or, 語法格式如下:
db.COLLECTION_NAME.find({$or:[{key1 : value1}, {key2 : value2}]}).pretty()
即
db.COLLECTION_NAME.find(
{
$or:[
{key1 : value1},
{key2 : value2}
]
}
).pretty()
2.2.4 模糊查詢
查詢title包含”mc”的文檔
db.COLLECTION_NAME.find(title: /mc/)
查詢title字段以”mc”開頭的文檔:
db.COLLECTION_NAME.find(title: /^mc/)
查詢title字段以”mc”結尾的文檔:
db.COLLECTION_NAME.find(title: /mc$/)
2.2.5 limit和skip
如果需要在MongoDB中讀取指定數量的數據記錄, 可以使用MongoDB的limit()方法, limit()方法接受一個數字參數, 該參數指定從MongoDB中讀取的記錄條數.
db.COLLECTION_NAME.find().limit(NUMBER)
除了可以使用limit()方法來讀取指定數量的數據外, 還可以使用skip()方法來跳過指定數量的數據, skip方法同樣接受一個數字參數作為跳過的記錄條數.
db.COLLECTION_NAME.find().limit(NUMBER).skip(NUMBER)
skip()方法默認參數為0
2.2.6 sort排序
在MongoDB中使用sort()方法對數據進行排序, sort()方法可以通過參數指定排序的字段, 並通過1和-1來指定排序的方式, 其中1位升序排列, 而-1是降序排列.
db.COLLECTION_NAME.find().sort({KEY: 1/-1})
三, Java連接MongoDB
首先, 引入mongo坐標
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongo-java-driver</artifactId>
<version>3.6.3</version>
</dependency>
3.1 連接
package com.lmc.mongo;
import com.mongodb.MongoClient;
import com.mongodb.client.MongoDatabase;
/**
* @author: lmc
* @Description: 描述信息
* @version: 1.0
* @date: 2020/9/23 14:57
*/
public class MongoDBJDBC {
public static void main(String[] args) {
//連接到MongoDB數據庫
MongoClient mongoClient = new MongoClient("localhost", 27017);
MongoDatabase database = mongoClient.getDatabase("lmc");
}
}
3.2 集合
3.2.1 創建集合
//創建集合
database.createCollection("test");
3.2.2 獲取集合
//獲取集合
MongoCollection<Document> collection = database.getCollection("test");
3.2.3 插入文檔
//在集合中插入文檔
Document document = new Document("database", "mongoDB")
.append("desc", "nosql data")
.append("create", "lmc")
.append("age", 22);
collection.insertOne(document);
3.2.4 檢索文檔
//獲取迭代器FindIterable<Document>
FindIterable<Document> findIterable = collection.find();
//獲取游標MongoCursor<Document>
MongoCursor<Document> mongoCursor = findIterable.iterator();
//通過游標遍歷檢索文檔集合
while (mongoCursor.hasNext()) {
System.out.println(mongoCursor.next());
}
輸出結果
Document{{_id=5f6af94061b3021fe46a1cdc, database=mongoDB, desc=nosql data, create=lmc, age=22}}
3.2.5 更新文檔
//更新文檔
collection.updateMany(
Filters.eq("database", "mongoDB"),
new Document("$set", new Document("create", "hh"))
);
3.2.6 刪除文檔
//刪除符合條件的第一個文檔
collection.deleteOne(Filters.eq("create", "hh"));
//刪除符合條件的文檔
collection.deleteMany(Filters.eq("create", "lmc"));
四, Spring集成MongoDB
首先, 引入依賴 :
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
創建實體類 Article :
package com.lmc.beans;
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;
import java.util.List;
/**
* @author: lmc
* @Description: Article
* @version: 1.0
* @date: 2020/10/6 11:14
*/
@Document(collection = "article_info")
public class Article {
@Id
private String id;
@Field("title")
private String title;
@Field("url")
private String url;
@Field("tags")
private List<String> tags;
@Field("add_time")
private Date addTime;
......
}
註解解釋 :
- @Document : 標識是一個文檔, 等同於MySQL中的表, collection值表示MongoDB中集合的名稱.
- @Id : 為主鍵標識
- @Field : 字段標識, 指定值為字段名稱
4.1 插入數據
4.1.1 單條插入
/**
* 單條添加
*/
public void addOne() {
Article article = new Article();
article.setTitle("標題title");
article.setUrl("http://localhost/article/");
article.setTags(Arrays.asList("java", "python", "php"));
article.setAddTime(new Date());
mongoTemplate.save(article);
}
4.1.2 批量插入
/**
* 批量添加
*/
public void addBatch() {
List<Article> articles = new ArrayList<Article>();
for (int i = 0; i < 10; ++i) {
Article article = new Article();
article.setTitle("標題title" + i);
article.setUrl("http://localhost/article/" + i);
article.setTags(Arrays.asList("java", "python", "php"));
article.setAddTime(new Date());
articles.add(article);
}
mongoTemplate.insert(articles, Article.class);
}
4.2 刪除數據
4.2.1 簡單刪除
/**
* 條件刪除, 通過類名
*/
public void deleteByTitleClass() {
Query query = Query.query(Criteria.where("title").is("標題title9"));
mongoTemplate.remove(query, Article.class);
}
/**
* 條件刪除, 通過集合名稱
*/
public void deleteByTitleCollection() {
Query query = Query.query(Criteria.where("title").is("標題title8"));
mongoTemplate.remove(query, "article_info");
}
4.2.2 刪除並返回
/**
* 刪除一條數據並返回
* @return
*/
public Article deleteOneReturn() {
Query query = Query.query(Criteria.where("title").is("標題title7"));
Article article = mongoTemplate.findAndRemove(query, Article.class);
return article;
}
/**
* 刪除所有數據並返回
* @return
*/
public List<Article> deleteAllReturn() {
Query query = Query.query(Criteria.where("title").is("標題title6"));
List<Article> articles = mongoTemplate.findAllAndRemove(query, Article.class);
return articles;
}
4.3 查詢數據
4.3.1 簡單條件查詢
/**
* 條件查詢一條數據
* @return
*/
public Article getOneByTitle() {
Query query = Query.query(Criteria.where("title").is("標題title"));
Article article = mongoTemplate.findOne(query, Article.class);
return article;
}
/**
* 條件查詢所有數據和數量
* @return
*/
public List<Article> getAllByTitle() {
List<String> tags = Arrays.asList("java", "python", "php", "r");
Query query = Query.query(Criteria.where("tags").in(tags));
List<Article> articles = mongoTemplate.find(query, Article.class);
//查詢符合條件數量
long count = mongoTemplate.count(query, Article.class);
System.out.println("the count is : " + count);
return articles;
}
/**
* 獲取所有數據
* @return
*/
public List<Article> getAll() {
List<Article> articles = mongoTemplate.findAll(Article.class);
return articles;
}
4.3.2 查詢條件
方法 | 描述 | 示例 |
---|---|---|
is() | 等於 | Criteria.where(“title”).is(“標題title”) |
in() | 包含 | Criteria.where(“tags”).in(Arrays.asList(“java”, “python”, “php”)) |
ne() | 不等於 | Criteria.where(“title”).ne(“標題title”) |
lt() | 小於 | Criteria.where(“money”).lt(100) |
gt().lt() | 範圍查詢 | Criteria.where(“money”).gt(1).lt(9) |
regex() | 模糊查詢 | Criteria.where(“title”).regex(“標題t”) |
orOperetor() | or查詢 | Criteria.where(“”).orOperetor(Criteria.where(“title”).is(“標題title”), Criteria.where(“title”).is(“標題title2”)) |
andOperetor() | and查詢 | Criteria.where(“”).andOperetor(Criteria.where(“title”).is(“標題title”), Criteria.where(“title”).is(“標題title2”)) |
4.4 修改數據
4.4.1 簡單條件修改
/**
* 普通修改
*/
public void updateByTitle() {
Query query = Query.query(Criteria.where("title").is("標題title"));
Update update = Update.update("url", "http://localhost/article/updateByTitle");
//修改第一條符合條件記錄
mongoTemplate.updateFirst(query, update, Article.class);
//修改所有符合條件記錄
mongoTemplate.updateMulti(query, update, Article.class);
}
4.4.2 修改, 添加字段
/**
* 有則修改數據, 無則添加一個字段
*/
public void updateAddColumn() {
Query query = Query.query(Criteria.where("title").is("標題title0"));
//set方法更新的key不存在則創建一個新的key
Update update = Update.update("money", 100).set("money", 100);
mongoTemplate.updateMulti(query, update, Article.class);
}
4.4.3 修改, 修改字段
/**
* 修改字段
*/
public void updateModifyColumn() {
Query query = Query.query(Criteria.where("title").is("標題title0"));
//rename將查詢記錄中addTime字段改名為time
Update update = Update.update("money", 100).rename("addTime", "time");
mongoTemplate.updateMulti(query, update, Article.class);
}
4.4.4 修改, 刪除字段
/**
* 刪除字段
*/
public void updateDelColumn() {
Query query = Query.query(Criteria.where("title").is("標題title0"));
//unset將刪除query查詢中所有time字段
Update update = Update.update("money", 100).unset("time");
mongoTemplate.updateMulti(query, update, Article.class);
}
4.4.5 修改, 字段累加
/**
* 修改, 累加
*/
public void updateInc() {
Query query = Query.query(Criteria.where("title").is("標題title0"));
//inc用於累加操作
Update update = Update.update("url", "http://localhost/article/0").inc("money", 100);
mongoTemplate.updateMulti(query, update, Article.class);
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/81597.html