'十次方社交系統 第3章-文檔型數據庫MongoDB'

"

學習目標:

理解MongoDb的特點和體系結構

掌握常用的MongoDB命令

能夠運用Java操作MongoDB

使用SpringDataMongoDB完成吐槽微服務的開發

1MongoDB簡介

1.1吐槽和評論數據特點分析

吐槽和評論兩項功能存在以下特點:

(1)數據量大

(2)寫入操作頻繁

(3)價值較低

對於這樣的數據,我們更適合使用MongoDB來實現數據的存儲

1.2什麼是MongoDB

MongoDB 是一個跨平臺的,面向文檔的數據庫,是當前 NoSQL 數據庫產品中最熱門的一種。它介於關係數據庫和非關係數據庫之間,是非關係數據庫當中功能最豐富,最 像關係數據庫的產品。它支持的數據結構非常鬆散,是類似 JSON 的 BSON 格式,因此可以存儲比較複雜的數據類型。

MongoDB 的官方網站地址是:http://www.mongodb.org/

"

學習目標:

理解MongoDb的特點和體系結構

掌握常用的MongoDB命令

能夠運用Java操作MongoDB

使用SpringDataMongoDB完成吐槽微服務的開發

1MongoDB簡介

1.1吐槽和評論數據特點分析

吐槽和評論兩項功能存在以下特點:

(1)數據量大

(2)寫入操作頻繁

(3)價值較低

對於這樣的數據,我們更適合使用MongoDB來實現數據的存儲

1.2什麼是MongoDB

MongoDB 是一個跨平臺的,面向文檔的數據庫,是當前 NoSQL 數據庫產品中最熱門的一種。它介於關係數據庫和非關係數據庫之間,是非關係數據庫當中功能最豐富,最 像關係數據庫的產品。它支持的數據結構非常鬆散,是類似 JSON 的 BSON 格式,因此可以存儲比較複雜的數據類型。

MongoDB 的官方網站地址是:http://www.mongodb.org/

十次方社交系統 第3章-文檔型數據庫MongoDB

1.3MongoDB特點

MongoDB 最大的特點是他支持的查詢語言非常強大,其語法有點類似於面向對象的查詢語言,幾乎可以實現類似關係數據庫單表查詢的絕大部分功能,而且還支持對數據建 立索引。它是一個面向集合的,模式自由的文檔型數據庫。

具體特點總結如下:

(1)面向集合存儲,易於存儲對象類型的數據

(2)模式自由

(3)支持動態查詢

(4)支持完全索引,包含內部對象

(5)支持複製和故障恢復

(6)使用高效的二進制數據存儲,包括大型對象(如視頻等)

(7)自動處理碎片,以支持雲計算層次的擴展性

(8)支持 Python,PHP,Ruby,Java,C,C#,Javascript,Perl 及 C++語言的驅動程序,

社區中也提供了對 Erlang 及.NET 等平臺的驅動程序

(9)文件存儲格式為 BSON(一種 JSON 的擴展)

1.4MongoDB體系結構

MongoDB 的邏輯結構是一種層次結構。主要由:文檔(document)、集合(collection)、數據庫(database)這三部分組成的。邏輯結構是面向用戶的,用戶使用 MongoDB 開發應用程序使用的就是邏輯結構。

(1)MongoDB 的文檔(document),相當於關係數據庫中的一行記錄。

(2)多個文檔組成一個集合(collection),相當於關係數據庫的表。

(3)多個集合(collection),邏輯上組織在一起,就是數據庫(database)。

(4)一個 MongoDB 實例支持多個數據庫(database)。

文檔(document)、集合(collection)、數據庫(database)的層次結構如下圖:

"

學習目標:

理解MongoDb的特點和體系結構

掌握常用的MongoDB命令

能夠運用Java操作MongoDB

使用SpringDataMongoDB完成吐槽微服務的開發

1MongoDB簡介

1.1吐槽和評論數據特點分析

吐槽和評論兩項功能存在以下特點:

(1)數據量大

(2)寫入操作頻繁

(3)價值較低

對於這樣的數據,我們更適合使用MongoDB來實現數據的存儲

1.2什麼是MongoDB

MongoDB 是一個跨平臺的,面向文檔的數據庫,是當前 NoSQL 數據庫產品中最熱門的一種。它介於關係數據庫和非關係數據庫之間,是非關係數據庫當中功能最豐富,最 像關係數據庫的產品。它支持的數據結構非常鬆散,是類似 JSON 的 BSON 格式,因此可以存儲比較複雜的數據類型。

MongoDB 的官方網站地址是:http://www.mongodb.org/

十次方社交系統 第3章-文檔型數據庫MongoDB

1.3MongoDB特點

MongoDB 最大的特點是他支持的查詢語言非常強大,其語法有點類似於面向對象的查詢語言,幾乎可以實現類似關係數據庫單表查詢的絕大部分功能,而且還支持對數據建 立索引。它是一個面向集合的,模式自由的文檔型數據庫。

具體特點總結如下:

(1)面向集合存儲,易於存儲對象類型的數據

(2)模式自由

(3)支持動態查詢

(4)支持完全索引,包含內部對象

(5)支持複製和故障恢復

(6)使用高效的二進制數據存儲,包括大型對象(如視頻等)

(7)自動處理碎片,以支持雲計算層次的擴展性

(8)支持 Python,PHP,Ruby,Java,C,C#,Javascript,Perl 及 C++語言的驅動程序,

社區中也提供了對 Erlang 及.NET 等平臺的驅動程序

(9)文件存儲格式為 BSON(一種 JSON 的擴展)

1.4MongoDB體系結構

MongoDB 的邏輯結構是一種層次結構。主要由:文檔(document)、集合(collection)、數據庫(database)這三部分組成的。邏輯結構是面向用戶的,用戶使用 MongoDB 開發應用程序使用的就是邏輯結構。

(1)MongoDB 的文檔(document),相當於關係數據庫中的一行記錄。

(2)多個文檔組成一個集合(collection),相當於關係數據庫的表。

(3)多個集合(collection),邏輯上組織在一起,就是數據庫(database)。

(4)一個 MongoDB 實例支持多個數據庫(database)。

文檔(document)、集合(collection)、數據庫(database)的層次結構如下圖:

十次方社交系統 第3章-文檔型數據庫MongoDB

下表是MongoDB與MySQL數據庫邏輯結構概念的對比

"

學習目標:

理解MongoDb的特點和體系結構

掌握常用的MongoDB命令

能夠運用Java操作MongoDB

使用SpringDataMongoDB完成吐槽微服務的開發

1MongoDB簡介

1.1吐槽和評論數據特點分析

吐槽和評論兩項功能存在以下特點:

(1)數據量大

(2)寫入操作頻繁

(3)價值較低

對於這樣的數據,我們更適合使用MongoDB來實現數據的存儲

1.2什麼是MongoDB

MongoDB 是一個跨平臺的,面向文檔的數據庫,是當前 NoSQL 數據庫產品中最熱門的一種。它介於關係數據庫和非關係數據庫之間,是非關係數據庫當中功能最豐富,最 像關係數據庫的產品。它支持的數據結構非常鬆散,是類似 JSON 的 BSON 格式,因此可以存儲比較複雜的數據類型。

MongoDB 的官方網站地址是:http://www.mongodb.org/

十次方社交系統 第3章-文檔型數據庫MongoDB

1.3MongoDB特點

MongoDB 最大的特點是他支持的查詢語言非常強大,其語法有點類似於面向對象的查詢語言,幾乎可以實現類似關係數據庫單表查詢的絕大部分功能,而且還支持對數據建 立索引。它是一個面向集合的,模式自由的文檔型數據庫。

具體特點總結如下:

(1)面向集合存儲,易於存儲對象類型的數據

(2)模式自由

(3)支持動態查詢

(4)支持完全索引,包含內部對象

(5)支持複製和故障恢復

(6)使用高效的二進制數據存儲,包括大型對象(如視頻等)

(7)自動處理碎片,以支持雲計算層次的擴展性

(8)支持 Python,PHP,Ruby,Java,C,C#,Javascript,Perl 及 C++語言的驅動程序,

社區中也提供了對 Erlang 及.NET 等平臺的驅動程序

(9)文件存儲格式為 BSON(一種 JSON 的擴展)

1.4MongoDB體系結構

MongoDB 的邏輯結構是一種層次結構。主要由:文檔(document)、集合(collection)、數據庫(database)這三部分組成的。邏輯結構是面向用戶的,用戶使用 MongoDB 開發應用程序使用的就是邏輯結構。

(1)MongoDB 的文檔(document),相當於關係數據庫中的一行記錄。

(2)多個文檔組成一個集合(collection),相當於關係數據庫的表。

(3)多個集合(collection),邏輯上組織在一起,就是數據庫(database)。

(4)一個 MongoDB 實例支持多個數據庫(database)。

文檔(document)、集合(collection)、數據庫(database)的層次結構如下圖:

十次方社交系統 第3章-文檔型數據庫MongoDB

下表是MongoDB與MySQL數據庫邏輯結構概念的對比

十次方社交系統 第3章-文檔型數據庫MongoDB

1.5數據類型

基本數據類型

null:用於表示空值或者不存在的字段,{“x”:null}

布爾型:布爾類型有兩個值true和false,{“x”:true}

數值:shell默認使用64為浮點型數值。{“x”:3.14}或{“x”:3}。對於整型值,可以使用NumberInt(4字節符號整數)或NumberLong(8字節符號整數),{“x”:NumberInt(“3”)}{“x”:NumberLong(“3”)}

字符串:UTF-8字符串都可以表示為字符串類型的數據,{“x”:“呵呵”}

日期:日期被存儲為自新紀元依賴經過的毫秒數,不存儲時區,{“x”:new Date()}

正則表達式:查詢時,使用正則表達式作為限定條件,語法與JavaScript的正則表達式相同,{“x”[abc]/}

數組:數據列表或數據集可以表示為數組,{“x”: [“a“,“b”,”c”]}

內嵌文檔:文檔可以嵌套其他文檔,被嵌套的文檔作為值來處理,{“x”:{“y”:3 }}

對象Id:對象id是一個12字節的字符串,是文檔的唯一標識,{“x”: objectId() }

二進制數據:二進制數據是一個任意字節的字符串。它不能直接在shell中使用。如果要將非utf-字符保存到數據庫中,二進制數據是唯一的方式。

代碼:查詢和文檔中可以包括任何JavaScript代碼,{“x”:function(){/…/}}

2走進MongoDB

2.1MongoDB安裝與啟動

2.1.1window系統MongoDB安裝

安裝

雙擊“資源\\微服務相關\\配套軟件\\mongodb”中的“mongodb-win32-x86_64-2008plus- ssl-3.2.10-signed.msi” 按照提示步驟安裝即可。安裝完成後,軟件會安裝在C:\\Program Files\\MongoDB 目錄中。

我們要啟動的服務程序就是C:\\Program Files\\MongoDB\\Server\\3.2\\bin目錄下的mongod.exe, 為 了 方 便 我 們 每 次 啟 動 , 我 將 C:\\Program Files\\MongoDB\\Server\\3.2\\bin 設置到環境變量path中。

啟動

(1)首先打開命令提示符,創建一個用於存放數據的目錄

md d:\\data

(2)啟動服務

mongod ‐‐dbpath=d:\\data

我們在啟動信息中可以看到,mongoDB的默認端口是27017 如果我們想改變默認的啟動端口,可以通過–port來指定端口在命令提示符輸入以下命令即可完成登陸

mongo

退出mongodb

exit

1.5.2 Docker 環境下MongoDB安裝

在宿主機創建mongo容器

docker run ‐di ‐‐name=tensquare_mongo ‐p 27017:27017 mongo

遠程登陸

mongo 192.168.184.134

以吐槽表為例講解MongoDB常用命令

"

學習目標:

理解MongoDb的特點和體系結構

掌握常用的MongoDB命令

能夠運用Java操作MongoDB

使用SpringDataMongoDB完成吐槽微服務的開發

1MongoDB簡介

1.1吐槽和評論數據特點分析

吐槽和評論兩項功能存在以下特點:

(1)數據量大

(2)寫入操作頻繁

(3)價值較低

對於這樣的數據,我們更適合使用MongoDB來實現數據的存儲

1.2什麼是MongoDB

MongoDB 是一個跨平臺的,面向文檔的數據庫,是當前 NoSQL 數據庫產品中最熱門的一種。它介於關係數據庫和非關係數據庫之間,是非關係數據庫當中功能最豐富,最 像關係數據庫的產品。它支持的數據結構非常鬆散,是類似 JSON 的 BSON 格式,因此可以存儲比較複雜的數據類型。

MongoDB 的官方網站地址是:http://www.mongodb.org/

十次方社交系統 第3章-文檔型數據庫MongoDB

1.3MongoDB特點

MongoDB 最大的特點是他支持的查詢語言非常強大,其語法有點類似於面向對象的查詢語言,幾乎可以實現類似關係數據庫單表查詢的絕大部分功能,而且還支持對數據建 立索引。它是一個面向集合的,模式自由的文檔型數據庫。

具體特點總結如下:

(1)面向集合存儲,易於存儲對象類型的數據

(2)模式自由

(3)支持動態查詢

(4)支持完全索引,包含內部對象

(5)支持複製和故障恢復

(6)使用高效的二進制數據存儲,包括大型對象(如視頻等)

(7)自動處理碎片,以支持雲計算層次的擴展性

(8)支持 Python,PHP,Ruby,Java,C,C#,Javascript,Perl 及 C++語言的驅動程序,

社區中也提供了對 Erlang 及.NET 等平臺的驅動程序

(9)文件存儲格式為 BSON(一種 JSON 的擴展)

1.4MongoDB體系結構

MongoDB 的邏輯結構是一種層次結構。主要由:文檔(document)、集合(collection)、數據庫(database)這三部分組成的。邏輯結構是面向用戶的,用戶使用 MongoDB 開發應用程序使用的就是邏輯結構。

(1)MongoDB 的文檔(document),相當於關係數據庫中的一行記錄。

(2)多個文檔組成一個集合(collection),相當於關係數據庫的表。

(3)多個集合(collection),邏輯上組織在一起,就是數據庫(database)。

(4)一個 MongoDB 實例支持多個數據庫(database)。

文檔(document)、集合(collection)、數據庫(database)的層次結構如下圖:

十次方社交系統 第3章-文檔型數據庫MongoDB

下表是MongoDB與MySQL數據庫邏輯結構概念的對比

十次方社交系統 第3章-文檔型數據庫MongoDB

1.5數據類型

基本數據類型

null:用於表示空值或者不存在的字段,{“x”:null}

布爾型:布爾類型有兩個值true和false,{“x”:true}

數值:shell默認使用64為浮點型數值。{“x”:3.14}或{“x”:3}。對於整型值,可以使用NumberInt(4字節符號整數)或NumberLong(8字節符號整數),{“x”:NumberInt(“3”)}{“x”:NumberLong(“3”)}

字符串:UTF-8字符串都可以表示為字符串類型的數據,{“x”:“呵呵”}

日期:日期被存儲為自新紀元依賴經過的毫秒數,不存儲時區,{“x”:new Date()}

正則表達式:查詢時,使用正則表達式作為限定條件,語法與JavaScript的正則表達式相同,{“x”[abc]/}

數組:數據列表或數據集可以表示為數組,{“x”: [“a“,“b”,”c”]}

內嵌文檔:文檔可以嵌套其他文檔,被嵌套的文檔作為值來處理,{“x”:{“y”:3 }}

對象Id:對象id是一個12字節的字符串,是文檔的唯一標識,{“x”: objectId() }

二進制數據:二進制數據是一個任意字節的字符串。它不能直接在shell中使用。如果要將非utf-字符保存到數據庫中,二進制數據是唯一的方式。

代碼:查詢和文檔中可以包括任何JavaScript代碼,{“x”:function(){/…/}}

2走進MongoDB

2.1MongoDB安裝與啟動

2.1.1window系統MongoDB安裝

安裝

雙擊“資源\\微服務相關\\配套軟件\\mongodb”中的“mongodb-win32-x86_64-2008plus- ssl-3.2.10-signed.msi” 按照提示步驟安裝即可。安裝完成後,軟件會安裝在C:\\Program Files\\MongoDB 目錄中。

我們要啟動的服務程序就是C:\\Program Files\\MongoDB\\Server\\3.2\\bin目錄下的mongod.exe, 為 了 方 便 我 們 每 次 啟 動 , 我 將 C:\\Program Files\\MongoDB\\Server\\3.2\\bin 設置到環境變量path中。

啟動

(1)首先打開命令提示符,創建一個用於存放數據的目錄

md d:\\data

(2)啟動服務

mongod ‐‐dbpath=d:\\data

我們在啟動信息中可以看到,mongoDB的默認端口是27017 如果我們想改變默認的啟動端口,可以通過–port來指定端口在命令提示符輸入以下命令即可完成登陸

mongo

退出mongodb

exit

1.5.2 Docker 環境下MongoDB安裝

在宿主機創建mongo容器

docker run ‐di ‐‐name=tensquare_mongo ‐p 27017:27017 mongo

遠程登陸

mongo 192.168.184.134

以吐槽表為例講解MongoDB常用命令

十次方社交系統 第3章-文檔型數據庫MongoDB

2.2常用命令

2.2.1選擇和創建數據庫

選擇和創建數據庫的語法格式:

use 數據庫名稱

如果數據庫不存在則自動創建

以下語句創建spit數據庫

use spitdb

2.2.2插入與查詢文檔

插入文檔的語法格式:

db.集合名稱.insert(數據);

我們這裡可以插入以下測試數據:

db.spit.insert({content:"聽說十次方課程很給力呀",userid:"1011",nickname:"小雅",visits:NumberInt(902)})

查詢集合的語法格式:

db.集合名稱.find()

如果我們要查詢spit集合的所有文檔,我們輸入以下命令

db.spit.find()

這裡你會發現每條文檔會有一個叫_id的字段,這個相當於我們原來關係數據庫中表的主 鍵,當你在插入文檔記錄時沒有指定該字段,MongoDB會自動創建,其類型是ObjectID 類型。如果我們在插入文檔記錄時指定該字段也可以,其類型可以是ObjectID類型,也可以是MongoDB支持的任意類型。

輸入以下測試語句:

db.spit.insert({_id:"1",content:"我還是沒有想明白到底為啥出 錯",userid:"1012",nickname:"小明",visits:NumberInt(2020)});
db.spit.insert({_id:"2",content:"加班到半夜",userid:"1013",nickname:"凱撒",visits:NumberInt(1023)});
db.spit.insert({_id:"3",content:"手機流量超了咋
辦 ?",userid:"1013",nickname:" 凱 撒 ",visits:NumberInt(111)}); db.spit.insert({_id:"4",content:"堅持就是勝利",userid:"1014",nickname:"諾諾",visits:NumberInt(1223)});

如果我想按一定條件來查詢,比如我想查詢userid為1013的記錄,怎麼辦?很簡單!只要在find()中添加參數即可,參數也是json格式,如下:

db.spit.find({userid:'1013'})

如果你只需要返回符合條件的第一條數據,我們可以使用findOne命令來實現

db.spit.findOne({userid:'1013'})

如果你想返回指定條數的記錄,可以在find方法後調用limit來返回結果,例如:

db.spit.find().limit(3)

2.2.3修改與刪除文檔

修改文檔的語法結構:

db.集合名稱.update(條件,修改後的數據)

db.集合名稱.update(條件,修改後的數據)

db.spit.update({_id:"1"},{visits:NumberInt(1000)})

執行後,我們會發現,這條文檔除了visits字段其它字段都不見了,為了解決這個問題, 我們需要使用修改器$set來實現,命令如下:

db.spit.update({_id:"2"},{$set:{visits:NumberInt(2000)}})

這樣就OK啦。

刪除文檔的語法結構:

db.集合名稱.remove(條件)

以下語句可以將數據全部刪除,請慎用

db.spit.remove({})

如果刪除visits=1000的記錄,輸入以下語句

db.spit.remove({visits:1000})

2.2.4統計條數

統計記錄條件使用count()方法。以下語句統計spit集合的記錄數

db.spit.count()

如果按條件統計 ,例如:統計userid為1013的記錄條數

db.spit.count({userid:"1013"})

2.2.5模糊查詢

MongoDB的模糊查詢是通過正則表達式的方式實現的。格式為:

/模糊查詢字符串/

例如,我要查詢吐槽內容包含“流量”的所有文檔,代碼如下:

db.spit.find({content:/流量/})

如果要查詢吐槽內容中以“加班”開頭的,代碼如下:

db.spit.find({content:/^加班/})

2.2.6大於 小於 不等於

<, <=, >, >= 這個操作符也是很常用的,格式如下:

db.集合名稱.find({ "field" : { $gt: value }}) // 大於: field > value
db.集合名稱.find({ "field" : { $lt: value }}) // 小於: field < value
db.集合名稱.find({ "field" : { $gte: value }}) // 大於等於: field >= value
db.集合名稱.find({ "field" : { $lte: value }}) // 小於等於: field <= value
db.集合名稱.find({ "field" : { $ne: value }}) // 不等於: field != value

示例:查詢吐槽瀏覽量大於1000的記錄

db.spit.find({visits:{$gt:1000}})

2.2.7包含與不包含

包含使用$in操作符。

示例:查詢吐槽集合中userid字段包含1013和1014的文檔

db.spit.find({userid:{$in:["1013","1014"]}})

不包含使用$nin操作符。

示例:查詢吐槽集合中userid字段不包含1013和1014的文檔

db.spit.find({userid:{$nin:["1013","1014"]}})

2.2.8條件連接

我們如果需要查詢同時滿足兩個以上條件,需要使用$and操作符將條件進行關聯。(相當於SQL的and)

格式為:

$and:[ {\t},{\t},{ } ]

示例:查詢吐槽集合中visits大於等於1000 並且小於2000的文檔

db.spit.find({$and:[ {visits:{$gte:1000}} ,{visits:{$lt:2000} }]})

如果兩個以上條件之間是或者的關係,我們使用操作符進行關聯,與前面and的使用方式相同

格式為:

$or:[ {\t},{\t},{\t} ]

示例:查詢吐槽集合中userid為1013,或者瀏覽量小於2000的文檔記錄

db.spit.find({$or:[ {userid:"1013"} ,{visits:{$lt:2000} }]})

2.2.9列值增長

如果我們想實現對某列值在原有值的基礎上進行增加或減少,可以使用$inc運算符來實現

db.spit.update({_id:"2"},{$inc:{visits:NumberInt(1)}}\t)

3Java操作MongoDB

3.1mongodb-driver

mongodb-driver是mongo官方推出的java連接mongoDB的驅動包,相當於JDBC驅動。我們通過一個入門的案例來了解mongodb-driver的基本使用

3.1.1查詢全部記錄

(1)創建工程 mongoDemo, 引入依賴

<dependencies>
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongodb‐driver</artifactId>
<version>3.6.3</version>
</dependency>
</dependencies>

(2)創建測試類

/**
* MongoDb入門小demo
*/
public class MongoDemo {
public static void main(String[] args) {
MongoClient client=new MongoClient("192.168.184.134");//創建連接
MongoDatabase spitdb = client.getDatabase("spitdb");//打開數據庫MongoCollection<Document> spit = spitdb.getCollection("spit");//
獲取集合合
FindIterable<Document> documents = spit.find();//查詢記錄獲取文檔集
for(Document document:documents){ //
System.out.println("內容:"+\tdocument.getString("content"));
System.out.println("用戶ID:"+document.getString("userid")); System.out.println("瀏覽量:"+document.getInteger("visits"));
}
client.close();//關閉連接
}
}

3.1.2條件查詢

BasicDBObject對象:表示一個具體的記錄,BasicDBObject實現了DBObject,是key- value的數據結構,用起來和HashMap是基本一致的。

(1)查詢userid為1013的記錄

public class MongoDemo1 {
public static void main(String[] args) {
MongoClient client=new MongoClient("192.168.184.134");//創建連接
MongoDatabase spitdb = client.getDatabase("spitdb");//打開數據庫MongoCollection<Document> spit = spitdb.getCollection("spit");//獲取集合條件
BasicDBObject bson=new BasicDBObject("userid","1013");// 構建查詢FindIterable<Document> documents = spit.find(bson);//查詢記錄獲取結果集合
for(Document document:documents){ //
System.out.println("內容:"+\tdocument.getString("content"));
System.out.println("用戶ID:"+document.getString("userid"));
System.out.println("瀏覽量:"+document.getInteger("visits"));
}
client.close();//關閉連接
}
}

(2)查詢瀏覽量大於1000的記錄

public class MongoDemo2 {
public static void main(String[] args) {
MongoClient client=new MongoClient("192.168.184.134");//創建連接
MongoDatabase spitdb = client.getDatabase("spitdb");//打開數據庫
MongoCollection<Document> spit = spitdb.getCollection("spit");//獲取集合
BasicDBObject bson=new BasicDBObject("visits",new BasicDBObject("$gt",1000) );// 構建查詢條件
FindIterable<Document> documents = spit.find(bson);//查詢記錄獲取結果集合
for(Document document:documents){ //
System.out.println("內容:"+\tdocument.getString("content"));
System.out.println("用戶ID:"+document.getString("userid"));
System.out.println("瀏覽量:"+document.getInteger("visits"));
}
client.close();//關閉連接
}
}

3.1.3插入數據

public class MongoDemo3 {
public static void main(String[] args) {
MongoClient client=new MongoClient("192.168.184.134");//創建連接
MongoDatabase spitdb = client.getDatabase("spitdb");//打開數據庫
MongoCollection<Document> spit = spitdb.getCollection("spit");//獲取集合
Map<String,Object> map=new HashMap(); map.put("content","我要吐槽");
map.put("userid","9999");
map.put("visits",123); map.put("publishtime",new Date());
Document document=new Document(map);
spit.insertOne(document);//插入數據client.close();
}
}

3.2SpringDataMongoDB

SpringData家族成員之一,用於操作MongoDb的持久層框架,封裝了底層的mongodb- driver。

官網主頁: https://projects.spring.io/spring-data-mongodb/

我們十次方項目的吐槽微服務就採用SpringDataMongoDB框架

4吐槽微服務

4.1需求分析

採用SpringDataMongoDB框架實現吐槽微服務的持久層。實現功能:

(1)基本增刪改查API

(2)根據上級ID查詢吐槽列表

(3)吐槽點贊

(4)發佈吐槽

4.2代碼編寫

4.2.1模塊搭建

(1)搭建子模塊 tensquare_spit

(2)pom.xml引入依賴

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring‐boot‐starter‐data‐mongodb</artifactId>
</dependency>
<dependency>
<groupId>com.tensquare</groupId>
<artifactId>tensquare_common</artifactId>
<version>1.0‐SNAPSHOT</version>
</dependency>

(3)創建application.yml

server: port: 9006
spring: application:
name: tensquare‐spit #指定服務名
data:
mongodb:
host: 192.168.184.134
database: spitdb

(4)創建啟動類

@SpringBootApplication
public class SpitApplication {
public static void main(String[] args) {
SpringApplication.run(SpitApplication.class, args);
}
@Bean
public IdWorker idWorkker(){ return new IdWorker(1, 1);
}
}

4.2.2基本增刪改查API實現

(1)創建實體類

創建包com.tensquare.spit,包下建包pojo 用於存放實體類,創建實體類

/**

*吐槽

*@author Administrator

*

*/

public class Spit implements Serializable{

@Id

private String _id;

private String content;

private Date publishtime;

private String userid;

private String nickname;

private Integer visits;

private Integer thumbup;

private Integer share;

private Integer comment;

private String state;

private String parentid;

// getter and setter .....

}

(2)創建數據訪問接口

com.tensquare.spit包下創建dao包,包下創建接口

/**
*吐槽數據訪問層
*@author Administrator
*
*/
public interface SpitDao extends MongoRepository<Spit, String>{
}

(3)創建業務邏輯類

com.tensquare.spit包下創建service包,包下創建類

@Service
public class SpitService {
@Autowired
private SpitDao spitDao;
@Autowired
private IdWorker idWorker;
/**
*查詢全部記錄
*@return
*/
public List<Spit> findAll(){ return spitDao.findAll();
}
/**
*根據主鍵查詢實體
*@param id
*@return
*/
public Spit findById(String id){
Spit spit = spitDao.findById(id).get(); return spit;
}
/**
*增加
*@param spit
*/
public void add(Spit spit) { spit.set_id(idWorker.nextId()+""); //主鍵值spitDao.save(spit);
}
/**
*修改
*@param spit
*/
public void update(Spit spit) {
spitDao.save(spit);
}
/**
*刪除
*@param id
*/
public void deleteById(String id) { spitDao.deleteById(id);
}
}

(4)com.tensquare.spit包下創建controller類

@RestController @CrossOrigin @RequestMapping("/spit")
public class SpitController {
@Autowired
private SpitService spitService;
/**
*查詢全部數據
*@return
*/
@RequestMapping(method= RequestMethod.GET)
public Result findAll(){
return new Result(true, StatusCode.OK,"查詢成
功",spitService.findAll());
}
/**
*根據ID查詢
*@param id ID
*@return
*/ @RequestMapping(value="/{id}",method=RequestMethod.GET)
public Result findOne(@PathVariable String id){
return new Result(true,StatusCode.OK,"查詢成
功",spitService.findById(id));
}
/**
*增加
*@param spit
*/ @RequestMapping(method=RequestMethod.POST)
public Result add(@RequestBody Spit spit\t){
spitService.add(spit);
return new Result(true,StatusCode.OK,"增加成功");
}
/**
*修改
*@param spit
*/ @RequestMapping(value="/{id}",method=RequestMethod.PUT)
public Result update(@RequestBody Spit spit,@PathVariable String id )
{
spit.set_id(id); spitService.update(spit);
return new Result(true,StatusCode.OK,"修改成功");
}
/**
*刪除
*@param id
*/ @RequestMapping(value="/{id}",method=RequestMethod.DELETE)
public Result deleteById(@PathVariable String id ){
spitService.deleteById(id);
return new Result(true,StatusCode.OK,"刪除成功");
}
}

4.2.3根據上級ID查詢吐槽列表

(1)SpitDao新增方法定義

/**
*根據上級ID查詢吐槽列表(分頁)
*@param parentid
*@param pageable
*@return
*/
public Page<Spit> findByParentid(String parentid,Pageable pageable);

(2)SpitService新增方法

/**
*根據上級ID查詢吐槽列表
*@param parentid
*@param page
*@param size
*@return
*/
public Page<Spit> findByParentid(String parentid,int page, int size){
PageRequest pageRequest = PageRequest.of(page‐1, size);
return spitDao.findByParentid(parentid, pageRequest);
}

(3)SpitController新增方法

/**

*根據上級ID查詢吐槽分頁數據

*@param page

*@param size

*@return

*/

@RequestMapping(value="/comment/{parentId}/{page}/{size}",method=RequestM

ethod.GET)

public Result findByParentid(@PathVariable String parentId, @PathVariable int page,@PathVariable int size){

Page<Spit> pageList = spitService.findByParentid(parentId,page,

size);

return new Result(true,StatusCode.OK," 查 詢 成 功 ",

new PageResult<Spit>(pageList.getTotalElements(), pageList.getContent() ) );

}

4.2.4吐槽點贊

我們看一下以下點讚的代碼: SpitService 新增updateThumbup方法

public void updateThumbup(String id){
Spit spit = spitDao.findById(id).get();
spit.setThumbup(spit.getThumbup()+1);
spitDao.save(spit);
}

以上方法雖然實現起來比較簡單,但是執行效率並不高,因為我只需要將點贊數加1就可以了,沒必要查詢出所有字段修改後再更新所有字段。

我們可以使用MongoTemplate類來實現對某列的操作。

(1)修改SpitService

@Autowired

private MongoTemplate mongoTemplate;

/**

*點贊

*@param id

*/

public void updateThumbup(String id){ Query query=new Query();

query.addCriteria(Criteria.where("_id").is(id));

Update update=new Update();

update.inc("thumbup",1);

mongoTemplate.updateFirst(query,update,"spit");

}

(2)SpitController新增方法

* @return
*/ @RequestMapping(value="/thumbup/{id}",method=RequestMethod.PUT)
public Result updateThumbup(@PathVariable String id){
spitService.updateThumbup(id);
return new Result(true,StatusCode.OK,"點贊成功");
}

4.2.5控制不能重複點贊

我們可以通過redis控制用戶不能重複點贊

(1)首先引入依賴

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring‐boot‐starter‐data‐redis</artifactId>
</dependency>

(2)修改application.yml

redis:
host: 192.168.184.135

(3)修改SpitController代碼邏輯

@Autowired

private RedisTemplate redisTemplate;

/**

*吐槽點贊

*@param id

*@return

*/

@RequestMapping(value = "/thumbup/{id}", method = RequestMethod.PUT)

public Result updateThumbup(@PathVariable String id){

//判斷用戶是否點過贊

String userid="2023";// 後邊我們會修改為當前登陸的用戶

if(redisTemplate.opsForValue().get("thumbup_"+userid+"_"+ id)!=null){

return new Result(false,StatusCode.REPERROR,"你已經點過讚了");

}

spitService.updateThumbup(id);

redisTemplate.opsForValue().set( "thumbup_"+userid+"_"+ id,"1");

return new Result(true,StatusCode.OK,"點贊成功");

}

4.2.6發佈吐槽

修改SpitService的add方法

/**
*發佈吐槽(或吐槽評論)
*@param spit
*/
public void add(Spit spit){
spit.set_id( idWorker.nextId()+"" );
spit.setPublishtime(new Date());//發佈日期
spit.setVisits(0);//瀏覽量spit.setShare(0);//分享數
spit.setThumbup(0);//點贊數
spit.setComment(0);//回覆數spit.setState("1");//狀態
if(spit.getParentid()!=null && !"".equals(spit.getParentid())){//
如果存在上級ID,評論
Query query=new Query();
query.addCriteria(Criteria.where("_id").is(spit.getParentid()));
Update update=new Update(); update.inc("comment",1);
mongoTemplate.updateFirst(query,update,"spit");
}
spitDao.save(spit);
}

5文章評論功能開發

5.1表結構分析

集合結構:

"

學習目標:

理解MongoDb的特點和體系結構

掌握常用的MongoDB命令

能夠運用Java操作MongoDB

使用SpringDataMongoDB完成吐槽微服務的開發

1MongoDB簡介

1.1吐槽和評論數據特點分析

吐槽和評論兩項功能存在以下特點:

(1)數據量大

(2)寫入操作頻繁

(3)價值較低

對於這樣的數據,我們更適合使用MongoDB來實現數據的存儲

1.2什麼是MongoDB

MongoDB 是一個跨平臺的,面向文檔的數據庫,是當前 NoSQL 數據庫產品中最熱門的一種。它介於關係數據庫和非關係數據庫之間,是非關係數據庫當中功能最豐富,最 像關係數據庫的產品。它支持的數據結構非常鬆散,是類似 JSON 的 BSON 格式,因此可以存儲比較複雜的數據類型。

MongoDB 的官方網站地址是:http://www.mongodb.org/

十次方社交系統 第3章-文檔型數據庫MongoDB

1.3MongoDB特點

MongoDB 最大的特點是他支持的查詢語言非常強大,其語法有點類似於面向對象的查詢語言,幾乎可以實現類似關係數據庫單表查詢的絕大部分功能,而且還支持對數據建 立索引。它是一個面向集合的,模式自由的文檔型數據庫。

具體特點總結如下:

(1)面向集合存儲,易於存儲對象類型的數據

(2)模式自由

(3)支持動態查詢

(4)支持完全索引,包含內部對象

(5)支持複製和故障恢復

(6)使用高效的二進制數據存儲,包括大型對象(如視頻等)

(7)自動處理碎片,以支持雲計算層次的擴展性

(8)支持 Python,PHP,Ruby,Java,C,C#,Javascript,Perl 及 C++語言的驅動程序,

社區中也提供了對 Erlang 及.NET 等平臺的驅動程序

(9)文件存儲格式為 BSON(一種 JSON 的擴展)

1.4MongoDB體系結構

MongoDB 的邏輯結構是一種層次結構。主要由:文檔(document)、集合(collection)、數據庫(database)這三部分組成的。邏輯結構是面向用戶的,用戶使用 MongoDB 開發應用程序使用的就是邏輯結構。

(1)MongoDB 的文檔(document),相當於關係數據庫中的一行記錄。

(2)多個文檔組成一個集合(collection),相當於關係數據庫的表。

(3)多個集合(collection),邏輯上組織在一起,就是數據庫(database)。

(4)一個 MongoDB 實例支持多個數據庫(database)。

文檔(document)、集合(collection)、數據庫(database)的層次結構如下圖:

十次方社交系統 第3章-文檔型數據庫MongoDB

下表是MongoDB與MySQL數據庫邏輯結構概念的對比

十次方社交系統 第3章-文檔型數據庫MongoDB

1.5數據類型

基本數據類型

null:用於表示空值或者不存在的字段,{“x”:null}

布爾型:布爾類型有兩個值true和false,{“x”:true}

數值:shell默認使用64為浮點型數值。{“x”:3.14}或{“x”:3}。對於整型值,可以使用NumberInt(4字節符號整數)或NumberLong(8字節符號整數),{“x”:NumberInt(“3”)}{“x”:NumberLong(“3”)}

字符串:UTF-8字符串都可以表示為字符串類型的數據,{“x”:“呵呵”}

日期:日期被存儲為自新紀元依賴經過的毫秒數,不存儲時區,{“x”:new Date()}

正則表達式:查詢時,使用正則表達式作為限定條件,語法與JavaScript的正則表達式相同,{“x”[abc]/}

數組:數據列表或數據集可以表示為數組,{“x”: [“a“,“b”,”c”]}

內嵌文檔:文檔可以嵌套其他文檔,被嵌套的文檔作為值來處理,{“x”:{“y”:3 }}

對象Id:對象id是一個12字節的字符串,是文檔的唯一標識,{“x”: objectId() }

二進制數據:二進制數據是一個任意字節的字符串。它不能直接在shell中使用。如果要將非utf-字符保存到數據庫中,二進制數據是唯一的方式。

代碼:查詢和文檔中可以包括任何JavaScript代碼,{“x”:function(){/…/}}

2走進MongoDB

2.1MongoDB安裝與啟動

2.1.1window系統MongoDB安裝

安裝

雙擊“資源\\微服務相關\\配套軟件\\mongodb”中的“mongodb-win32-x86_64-2008plus- ssl-3.2.10-signed.msi” 按照提示步驟安裝即可。安裝完成後,軟件會安裝在C:\\Program Files\\MongoDB 目錄中。

我們要啟動的服務程序就是C:\\Program Files\\MongoDB\\Server\\3.2\\bin目錄下的mongod.exe, 為 了 方 便 我 們 每 次 啟 動 , 我 將 C:\\Program Files\\MongoDB\\Server\\3.2\\bin 設置到環境變量path中。

啟動

(1)首先打開命令提示符,創建一個用於存放數據的目錄

md d:\\data

(2)啟動服務

mongod ‐‐dbpath=d:\\data

我們在啟動信息中可以看到,mongoDB的默認端口是27017 如果我們想改變默認的啟動端口,可以通過–port來指定端口在命令提示符輸入以下命令即可完成登陸

mongo

退出mongodb

exit

1.5.2 Docker 環境下MongoDB安裝

在宿主機創建mongo容器

docker run ‐di ‐‐name=tensquare_mongo ‐p 27017:27017 mongo

遠程登陸

mongo 192.168.184.134

以吐槽表為例講解MongoDB常用命令

十次方社交系統 第3章-文檔型數據庫MongoDB

2.2常用命令

2.2.1選擇和創建數據庫

選擇和創建數據庫的語法格式:

use 數據庫名稱

如果數據庫不存在則自動創建

以下語句創建spit數據庫

use spitdb

2.2.2插入與查詢文檔

插入文檔的語法格式:

db.集合名稱.insert(數據);

我們這裡可以插入以下測試數據:

db.spit.insert({content:"聽說十次方課程很給力呀",userid:"1011",nickname:"小雅",visits:NumberInt(902)})

查詢集合的語法格式:

db.集合名稱.find()

如果我們要查詢spit集合的所有文檔,我們輸入以下命令

db.spit.find()

這裡你會發現每條文檔會有一個叫_id的字段,這個相當於我們原來關係數據庫中表的主 鍵,當你在插入文檔記錄時沒有指定該字段,MongoDB會自動創建,其類型是ObjectID 類型。如果我們在插入文檔記錄時指定該字段也可以,其類型可以是ObjectID類型,也可以是MongoDB支持的任意類型。

輸入以下測試語句:

db.spit.insert({_id:"1",content:"我還是沒有想明白到底為啥出 錯",userid:"1012",nickname:"小明",visits:NumberInt(2020)});
db.spit.insert({_id:"2",content:"加班到半夜",userid:"1013",nickname:"凱撒",visits:NumberInt(1023)});
db.spit.insert({_id:"3",content:"手機流量超了咋
辦 ?",userid:"1013",nickname:" 凱 撒 ",visits:NumberInt(111)}); db.spit.insert({_id:"4",content:"堅持就是勝利",userid:"1014",nickname:"諾諾",visits:NumberInt(1223)});

如果我想按一定條件來查詢,比如我想查詢userid為1013的記錄,怎麼辦?很簡單!只要在find()中添加參數即可,參數也是json格式,如下:

db.spit.find({userid:'1013'})

如果你只需要返回符合條件的第一條數據,我們可以使用findOne命令來實現

db.spit.findOne({userid:'1013'})

如果你想返回指定條數的記錄,可以在find方法後調用limit來返回結果,例如:

db.spit.find().limit(3)

2.2.3修改與刪除文檔

修改文檔的語法結構:

db.集合名稱.update(條件,修改後的數據)

db.集合名稱.update(條件,修改後的數據)

db.spit.update({_id:"1"},{visits:NumberInt(1000)})

執行後,我們會發現,這條文檔除了visits字段其它字段都不見了,為了解決這個問題, 我們需要使用修改器$set來實現,命令如下:

db.spit.update({_id:"2"},{$set:{visits:NumberInt(2000)}})

這樣就OK啦。

刪除文檔的語法結構:

db.集合名稱.remove(條件)

以下語句可以將數據全部刪除,請慎用

db.spit.remove({})

如果刪除visits=1000的記錄,輸入以下語句

db.spit.remove({visits:1000})

2.2.4統計條數

統計記錄條件使用count()方法。以下語句統計spit集合的記錄數

db.spit.count()

如果按條件統計 ,例如:統計userid為1013的記錄條數

db.spit.count({userid:"1013"})

2.2.5模糊查詢

MongoDB的模糊查詢是通過正則表達式的方式實現的。格式為:

/模糊查詢字符串/

例如,我要查詢吐槽內容包含“流量”的所有文檔,代碼如下:

db.spit.find({content:/流量/})

如果要查詢吐槽內容中以“加班”開頭的,代碼如下:

db.spit.find({content:/^加班/})

2.2.6大於 小於 不等於

<, <=, >, >= 這個操作符也是很常用的,格式如下:

db.集合名稱.find({ "field" : { $gt: value }}) // 大於: field > value
db.集合名稱.find({ "field" : { $lt: value }}) // 小於: field < value
db.集合名稱.find({ "field" : { $gte: value }}) // 大於等於: field >= value
db.集合名稱.find({ "field" : { $lte: value }}) // 小於等於: field <= value
db.集合名稱.find({ "field" : { $ne: value }}) // 不等於: field != value

示例:查詢吐槽瀏覽量大於1000的記錄

db.spit.find({visits:{$gt:1000}})

2.2.7包含與不包含

包含使用$in操作符。

示例:查詢吐槽集合中userid字段包含1013和1014的文檔

db.spit.find({userid:{$in:["1013","1014"]}})

不包含使用$nin操作符。

示例:查詢吐槽集合中userid字段不包含1013和1014的文檔

db.spit.find({userid:{$nin:["1013","1014"]}})

2.2.8條件連接

我們如果需要查詢同時滿足兩個以上條件,需要使用$and操作符將條件進行關聯。(相當於SQL的and)

格式為:

$and:[ {\t},{\t},{ } ]

示例:查詢吐槽集合中visits大於等於1000 並且小於2000的文檔

db.spit.find({$and:[ {visits:{$gte:1000}} ,{visits:{$lt:2000} }]})

如果兩個以上條件之間是或者的關係,我們使用操作符進行關聯,與前面and的使用方式相同

格式為:

$or:[ {\t},{\t},{\t} ]

示例:查詢吐槽集合中userid為1013,或者瀏覽量小於2000的文檔記錄

db.spit.find({$or:[ {userid:"1013"} ,{visits:{$lt:2000} }]})

2.2.9列值增長

如果我們想實現對某列值在原有值的基礎上進行增加或減少,可以使用$inc運算符來實現

db.spit.update({_id:"2"},{$inc:{visits:NumberInt(1)}}\t)

3Java操作MongoDB

3.1mongodb-driver

mongodb-driver是mongo官方推出的java連接mongoDB的驅動包,相當於JDBC驅動。我們通過一個入門的案例來了解mongodb-driver的基本使用

3.1.1查詢全部記錄

(1)創建工程 mongoDemo, 引入依賴

<dependencies>
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongodb‐driver</artifactId>
<version>3.6.3</version>
</dependency>
</dependencies>

(2)創建測試類

/**
* MongoDb入門小demo
*/
public class MongoDemo {
public static void main(String[] args) {
MongoClient client=new MongoClient("192.168.184.134");//創建連接
MongoDatabase spitdb = client.getDatabase("spitdb");//打開數據庫MongoCollection<Document> spit = spitdb.getCollection("spit");//
獲取集合合
FindIterable<Document> documents = spit.find();//查詢記錄獲取文檔集
for(Document document:documents){ //
System.out.println("內容:"+\tdocument.getString("content"));
System.out.println("用戶ID:"+document.getString("userid")); System.out.println("瀏覽量:"+document.getInteger("visits"));
}
client.close();//關閉連接
}
}

3.1.2條件查詢

BasicDBObject對象:表示一個具體的記錄,BasicDBObject實現了DBObject,是key- value的數據結構,用起來和HashMap是基本一致的。

(1)查詢userid為1013的記錄

public class MongoDemo1 {
public static void main(String[] args) {
MongoClient client=new MongoClient("192.168.184.134");//創建連接
MongoDatabase spitdb = client.getDatabase("spitdb");//打開數據庫MongoCollection<Document> spit = spitdb.getCollection("spit");//獲取集合條件
BasicDBObject bson=new BasicDBObject("userid","1013");// 構建查詢FindIterable<Document> documents = spit.find(bson);//查詢記錄獲取結果集合
for(Document document:documents){ //
System.out.println("內容:"+\tdocument.getString("content"));
System.out.println("用戶ID:"+document.getString("userid"));
System.out.println("瀏覽量:"+document.getInteger("visits"));
}
client.close();//關閉連接
}
}

(2)查詢瀏覽量大於1000的記錄

public class MongoDemo2 {
public static void main(String[] args) {
MongoClient client=new MongoClient("192.168.184.134");//創建連接
MongoDatabase spitdb = client.getDatabase("spitdb");//打開數據庫
MongoCollection<Document> spit = spitdb.getCollection("spit");//獲取集合
BasicDBObject bson=new BasicDBObject("visits",new BasicDBObject("$gt",1000) );// 構建查詢條件
FindIterable<Document> documents = spit.find(bson);//查詢記錄獲取結果集合
for(Document document:documents){ //
System.out.println("內容:"+\tdocument.getString("content"));
System.out.println("用戶ID:"+document.getString("userid"));
System.out.println("瀏覽量:"+document.getInteger("visits"));
}
client.close();//關閉連接
}
}

3.1.3插入數據

public class MongoDemo3 {
public static void main(String[] args) {
MongoClient client=new MongoClient("192.168.184.134");//創建連接
MongoDatabase spitdb = client.getDatabase("spitdb");//打開數據庫
MongoCollection<Document> spit = spitdb.getCollection("spit");//獲取集合
Map<String,Object> map=new HashMap(); map.put("content","我要吐槽");
map.put("userid","9999");
map.put("visits",123); map.put("publishtime",new Date());
Document document=new Document(map);
spit.insertOne(document);//插入數據client.close();
}
}

3.2SpringDataMongoDB

SpringData家族成員之一,用於操作MongoDb的持久層框架,封裝了底層的mongodb- driver。

官網主頁: https://projects.spring.io/spring-data-mongodb/

我們十次方項目的吐槽微服務就採用SpringDataMongoDB框架

4吐槽微服務

4.1需求分析

採用SpringDataMongoDB框架實現吐槽微服務的持久層。實現功能:

(1)基本增刪改查API

(2)根據上級ID查詢吐槽列表

(3)吐槽點贊

(4)發佈吐槽

4.2代碼編寫

4.2.1模塊搭建

(1)搭建子模塊 tensquare_spit

(2)pom.xml引入依賴

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring‐boot‐starter‐data‐mongodb</artifactId>
</dependency>
<dependency>
<groupId>com.tensquare</groupId>
<artifactId>tensquare_common</artifactId>
<version>1.0‐SNAPSHOT</version>
</dependency>

(3)創建application.yml

server: port: 9006
spring: application:
name: tensquare‐spit #指定服務名
data:
mongodb:
host: 192.168.184.134
database: spitdb

(4)創建啟動類

@SpringBootApplication
public class SpitApplication {
public static void main(String[] args) {
SpringApplication.run(SpitApplication.class, args);
}
@Bean
public IdWorker idWorkker(){ return new IdWorker(1, 1);
}
}

4.2.2基本增刪改查API實現

(1)創建實體類

創建包com.tensquare.spit,包下建包pojo 用於存放實體類,創建實體類

/**

*吐槽

*@author Administrator

*

*/

public class Spit implements Serializable{

@Id

private String _id;

private String content;

private Date publishtime;

private String userid;

private String nickname;

private Integer visits;

private Integer thumbup;

private Integer share;

private Integer comment;

private String state;

private String parentid;

// getter and setter .....

}

(2)創建數據訪問接口

com.tensquare.spit包下創建dao包,包下創建接口

/**
*吐槽數據訪問層
*@author Administrator
*
*/
public interface SpitDao extends MongoRepository<Spit, String>{
}

(3)創建業務邏輯類

com.tensquare.spit包下創建service包,包下創建類

@Service
public class SpitService {
@Autowired
private SpitDao spitDao;
@Autowired
private IdWorker idWorker;
/**
*查詢全部記錄
*@return
*/
public List<Spit> findAll(){ return spitDao.findAll();
}
/**
*根據主鍵查詢實體
*@param id
*@return
*/
public Spit findById(String id){
Spit spit = spitDao.findById(id).get(); return spit;
}
/**
*增加
*@param spit
*/
public void add(Spit spit) { spit.set_id(idWorker.nextId()+""); //主鍵值spitDao.save(spit);
}
/**
*修改
*@param spit
*/
public void update(Spit spit) {
spitDao.save(spit);
}
/**
*刪除
*@param id
*/
public void deleteById(String id) { spitDao.deleteById(id);
}
}

(4)com.tensquare.spit包下創建controller類

@RestController @CrossOrigin @RequestMapping("/spit")
public class SpitController {
@Autowired
private SpitService spitService;
/**
*查詢全部數據
*@return
*/
@RequestMapping(method= RequestMethod.GET)
public Result findAll(){
return new Result(true, StatusCode.OK,"查詢成
功",spitService.findAll());
}
/**
*根據ID查詢
*@param id ID
*@return
*/ @RequestMapping(value="/{id}",method=RequestMethod.GET)
public Result findOne(@PathVariable String id){
return new Result(true,StatusCode.OK,"查詢成
功",spitService.findById(id));
}
/**
*增加
*@param spit
*/ @RequestMapping(method=RequestMethod.POST)
public Result add(@RequestBody Spit spit\t){
spitService.add(spit);
return new Result(true,StatusCode.OK,"增加成功");
}
/**
*修改
*@param spit
*/ @RequestMapping(value="/{id}",method=RequestMethod.PUT)
public Result update(@RequestBody Spit spit,@PathVariable String id )
{
spit.set_id(id); spitService.update(spit);
return new Result(true,StatusCode.OK,"修改成功");
}
/**
*刪除
*@param id
*/ @RequestMapping(value="/{id}",method=RequestMethod.DELETE)
public Result deleteById(@PathVariable String id ){
spitService.deleteById(id);
return new Result(true,StatusCode.OK,"刪除成功");
}
}

4.2.3根據上級ID查詢吐槽列表

(1)SpitDao新增方法定義

/**
*根據上級ID查詢吐槽列表(分頁)
*@param parentid
*@param pageable
*@return
*/
public Page<Spit> findByParentid(String parentid,Pageable pageable);

(2)SpitService新增方法

/**
*根據上級ID查詢吐槽列表
*@param parentid
*@param page
*@param size
*@return
*/
public Page<Spit> findByParentid(String parentid,int page, int size){
PageRequest pageRequest = PageRequest.of(page‐1, size);
return spitDao.findByParentid(parentid, pageRequest);
}

(3)SpitController新增方法

/**

*根據上級ID查詢吐槽分頁數據

*@param page

*@param size

*@return

*/

@RequestMapping(value="/comment/{parentId}/{page}/{size}",method=RequestM

ethod.GET)

public Result findByParentid(@PathVariable String parentId, @PathVariable int page,@PathVariable int size){

Page<Spit> pageList = spitService.findByParentid(parentId,page,

size);

return new Result(true,StatusCode.OK," 查 詢 成 功 ",

new PageResult<Spit>(pageList.getTotalElements(), pageList.getContent() ) );

}

4.2.4吐槽點贊

我們看一下以下點讚的代碼: SpitService 新增updateThumbup方法

public void updateThumbup(String id){
Spit spit = spitDao.findById(id).get();
spit.setThumbup(spit.getThumbup()+1);
spitDao.save(spit);
}

以上方法雖然實現起來比較簡單,但是執行效率並不高,因為我只需要將點贊數加1就可以了,沒必要查詢出所有字段修改後再更新所有字段。

我們可以使用MongoTemplate類來實現對某列的操作。

(1)修改SpitService

@Autowired

private MongoTemplate mongoTemplate;

/**

*點贊

*@param id

*/

public void updateThumbup(String id){ Query query=new Query();

query.addCriteria(Criteria.where("_id").is(id));

Update update=new Update();

update.inc("thumbup",1);

mongoTemplate.updateFirst(query,update,"spit");

}

(2)SpitController新增方法

* @return
*/ @RequestMapping(value="/thumbup/{id}",method=RequestMethod.PUT)
public Result updateThumbup(@PathVariable String id){
spitService.updateThumbup(id);
return new Result(true,StatusCode.OK,"點贊成功");
}

4.2.5控制不能重複點贊

我們可以通過redis控制用戶不能重複點贊

(1)首先引入依賴

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring‐boot‐starter‐data‐redis</artifactId>
</dependency>

(2)修改application.yml

redis:
host: 192.168.184.135

(3)修改SpitController代碼邏輯

@Autowired

private RedisTemplate redisTemplate;

/**

*吐槽點贊

*@param id

*@return

*/

@RequestMapping(value = "/thumbup/{id}", method = RequestMethod.PUT)

public Result updateThumbup(@PathVariable String id){

//判斷用戶是否點過贊

String userid="2023";// 後邊我們會修改為當前登陸的用戶

if(redisTemplate.opsForValue().get("thumbup_"+userid+"_"+ id)!=null){

return new Result(false,StatusCode.REPERROR,"你已經點過讚了");

}

spitService.updateThumbup(id);

redisTemplate.opsForValue().set( "thumbup_"+userid+"_"+ id,"1");

return new Result(true,StatusCode.OK,"點贊成功");

}

4.2.6發佈吐槽

修改SpitService的add方法

/**
*發佈吐槽(或吐槽評論)
*@param spit
*/
public void add(Spit spit){
spit.set_id( idWorker.nextId()+"" );
spit.setPublishtime(new Date());//發佈日期
spit.setVisits(0);//瀏覽量spit.setShare(0);//分享數
spit.setThumbup(0);//點贊數
spit.setComment(0);//回覆數spit.setState("1");//狀態
if(spit.getParentid()!=null && !"".equals(spit.getParentid())){//
如果存在上級ID,評論
Query query=new Query();
query.addCriteria(Criteria.where("_id").is(spit.getParentid()));
Update update=new Update(); update.inc("comment",1);
mongoTemplate.updateFirst(query,update,"spit");
}
spitDao.save(spit);
}

5文章評論功能開發

5.1表結構分析

集合結構:

十次方社交系統 第3章-文檔型數據庫MongoDB

4.2.1新增評論

(1)修改tensquare_article工程的pom.xml

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring‐boot‐starter‐data‐mongodb</artifactId>
</dependency>

(2)修改application.yml ,在spring節點下新增配置

data:
mongodb:
host: 192.168.184.134
database: recruitdb

(3)創建實體類

/**
*文章評論(mongoDB)
*@author Administrator
*
*/
public class Comment implements Serializable{
@Id
private String _id;
private String articleid;
private String content;
private String userid;
private String parentid;
private Date publishdate;

//getter and setter....
}

(4)創建數據訪問接口

/**
*評論Dao
*@author Administrator
*
*/
public interface CommentDao extends MongoRepository<Comment, String> {
}

(5)創建業務邏輯類

@Service
public class CommentService {
@Autowired
private CommentDao commentDao;
@Autowired
private IdWorker idWorker;
public void add(Comment comment){
comment.setId( idWorker.nextId()+""\t); commentDao.save(comment);
}
}

(6)創建控制器類

@RestController

@CrossOrigin @RequestMapping("/comment")

public class CommentController {

@Autowired

private CommentService commentService;

@RequestMapping(method= RequestMethod.POST)

public Result save(@RequestBody Comment comment){ commentService.add(comment);

return new Result(true, StatusCode.OK, "提交成功 ");

}

}

4.2.2根據文章ID查詢評論列表

(1)CommentDao新增方法定義

/**
*根據文章ID查詢評論列表
*@param articleid
*@return
*/
public List<Comment> findByArticleid(String articleid);

(2)CommentService新增方法

public List<Comment> findByArticleid(String articleid){ 
return commentDao.findByArticleid(articleid);
}

(3)CommentController新增方法

@RequestMapping(value="/article/{articleid}",method= RequestMethod.GET) 
public Result findByArticleid(@PathVariable String articleid){
return new Result(true, StatusCode.OK, "查詢成功",
commentService.findByArticleid(articleid));
}

面試問題總結

你在項目中有沒有使用到mongodb?

你的工程是如何操作MongoDB的?

spring data mongodb

在項目的哪些場景下使用MongoDB ?

吐槽 、文章評論

為什麼在吐槽和文章評論中使用Mongodb而不使用mysql?

吐槽和評論都是數據量較大且價值較低的數據,為了減輕mysql的壓力,我們使用mongodb

"

相關推薦

推薦中...