Node項(xiàng)目中怎么操作MySQL?下面本篇文章就來(lái)給大家聊聊SQL管理數(shù)據(jù)庫(kù)的幾個(gè)語(yǔ)句,并介紹一下在Express項(xiàng)目中操作MySQL的方法,希望對(duì)大家有所幫助!
數(shù)據(jù)庫(kù)
數(shù)據(jù)庫(kù)(database)是用來(lái)組織、存儲(chǔ)和管理數(shù)據(jù)的倉(cāng)庫(kù)。當(dāng)今世界是一個(gè)充滿著數(shù)據(jù)的互聯(lián)網(wǎng)世界,充斥著大量的數(shù)據(jù)。數(shù)據(jù)的來(lái)源有很多,比如出行記錄、消費(fèi)記錄、瀏覽的網(wǎng)頁(yè)、發(fā)送的消息等等。除了文本類(lèi)型的數(shù)據(jù),圖像、音樂(lè)、聲音都是數(shù)據(jù)。為了方便管理互聯(lián)網(wǎng)世界中的數(shù)據(jù),就有了數(shù)據(jù)庫(kù)管理系統(tǒng)的概念(簡(jiǎn)稱(chēng):數(shù)據(jù)庫(kù))。用戶可以對(duì)數(shù)據(jù)庫(kù)中的數(shù)據(jù)進(jìn)行新增、查詢(xún)、更新、刪除等操作。
數(shù)據(jù)庫(kù)的分類(lèi):
MySQL數(shù)據(jù)庫(kù)(目前使用最廣泛、流行度最高的開(kāi)源免費(fèi)數(shù)據(jù)庫(kù);Community + Enterprise)
Oracle數(shù)據(jù)庫(kù)(收費(fèi))
SQL Server數(shù)據(jù)庫(kù) (收費(fèi))
Mongodb數(shù)據(jù)庫(kù)(Community + Enterprise)
比較:MySQL、Oracle、SQL Server屬于傳統(tǒng)型數(shù)據(jù)庫(kù)(又叫做:關(guān)系型數(shù)據(jù)庫(kù)或SQL數(shù)據(jù)庫(kù)),這三者的設(shè)計(jì)理念相同,用法比較類(lèi)似;而MongoDB屬于新型數(shù)據(jù)庫(kù)(又叫做:非關(guān)系型數(shù)據(jù)庫(kù)或NoSQL數(shù)據(jù)庫(kù)),它在一定程度上彌補(bǔ)了傳統(tǒng)型數(shù)據(jù)庫(kù)的缺陷。
傳統(tǒng)型數(shù)據(jù)庫(kù)的數(shù)據(jù)組織結(jié)構(gòu):在傳統(tǒng)型數(shù)據(jù)庫(kù)中,數(shù)據(jù)的組織結(jié)構(gòu)分為數(shù)據(jù)庫(kù)(database)、數(shù)據(jù)表(table)、數(shù)據(jù)行(row)、字段(field)這4大部分組成。
實(shí)際開(kāi)發(fā)中庫(kù)、表、行、字段的關(guān)系:在實(shí)際項(xiàng)目開(kāi)發(fā)中,一般情況下,每個(gè)項(xiàng)目都對(duì)應(yīng)獨(dú)立的數(shù)據(jù)庫(kù);不同的數(shù)據(jù),要存儲(chǔ)到數(shù)據(jù)庫(kù)的不同表中,例如:用戶數(shù)據(jù)存儲(chǔ)到users 表中,圖書(shū)數(shù)據(jù)存儲(chǔ)到 books表中;每個(gè)表中具體存儲(chǔ)哪些信息,由字段來(lái)決定,例如:我們可以為users 表設(shè)計(jì)id、username、password這3個(gè)字段;表中的行,代表每一條具體的數(shù)據(jù)。
MySQL的安裝與配置
對(duì)于開(kāi)發(fā)人員來(lái)講,只需安裝 MySQL Server 和 Navicat 這兩個(gè)軟件,就能滿足開(kāi)發(fā)需求了。
MySQL Server:專(zhuān)門(mén)用來(lái)提供數(shù)據(jù)存儲(chǔ)和服務(wù)的軟件
Navicat:可視化的MySQL管理工具,通過(guò)它可以方便的操作存儲(chǔ)在 MySQL Server中的數(shù)據(jù)
具體的安裝教程,可以參考一下我之前的文章:MySQL的安裝 。有了可視化工具,我們創(chuàng)建表和編輯表的數(shù)據(jù)就變得異常容易了。
SQL管理數(shù)據(jù)庫(kù)
SQL(英文全稱(chēng):Structured Query Language)是結(jié)構(gòu)化查詢(xún)語(yǔ)言,專(zhuān)門(mén)用來(lái)訪問(wèn)和處理數(shù)據(jù)庫(kù)的編程語(yǔ)言。能夠讓我們以編程的形式,操作數(shù)據(jù)庫(kù)里面的數(shù)據(jù)。
注意:
1)SQL是一門(mén)數(shù)據(jù)庫(kù)編程語(yǔ)言
2)使用 SQL 語(yǔ)言編寫(xiě)出來(lái)的代碼,叫做 SQL 語(yǔ)句
3)SQL語(yǔ)言只能在關(guān)系型數(shù)據(jù)庫(kù)中使用(例如:MySQL、Oracle、SQL server)。非關(guān)系型數(shù)據(jù)庫(kù)(例如:Mongodb)不支持SQL語(yǔ)言。
SELECT語(yǔ)句
用于從表中查詢(xún)數(shù)據(jù)。執(zhí)行的結(jié)果被存儲(chǔ)在一個(gè)結(jié)果表中(稱(chēng)為結(jié)果集)。其語(yǔ)法如下:(注意:SQL語(yǔ)句中的關(guān)鍵字對(duì)大小寫(xiě)不敏感,SELECT等效于select,F(xiàn)ROM等效于from)。
-- 這是注釋 -- 從 FROM 指定的【表中】,查詢(xún)出【所有的】數(shù)據(jù),* 表示【所有列】 SELECT * FROM 表名稱(chēng) -- 從 FROM 指定的【表中】,查詢(xún)出指定 列名稱(chēng) (字段) 的數(shù)據(jù) SELECT 列名稱(chēng) FROM 表名稱(chēng)
INSERT INTO語(yǔ)句
用于向數(shù)據(jù)表中插入新的數(shù)據(jù)行。
-- 向指定表中插入數(shù)據(jù),列的值通過(guò) values 一一指定 -- 列和值要一一對(duì)應(yīng),多個(gè)列和多個(gè)值之間,要使用英文逗號(hào)分隔 insert into table_name (列1,列2...) values (值1,值2,值3)
Update語(yǔ)句
用于修改表中的數(shù)據(jù)
-- 用 UPDATE 指定要更新哪個(gè)表中的數(shù)據(jù),用 SET 指定列對(duì)應(yīng)的新值,用 WHERE 指定更新的條件 update 表名稱(chēng) set 列名稱(chēng) = 新值 where 列名稱(chēng) = 某值
DELETE語(yǔ)句
用于刪除表中的行
-- 從指定的表中,根據(jù) WHERE 條件,刪除對(duì)應(yīng)的數(shù)據(jù)行 delete from 表名稱(chēng) where 列名稱(chēng) = 值
WHERE子句
用于限定選擇的標(biāo)準(zhǔn),在SELECT、UPDATE、DELETE語(yǔ)句中,皆可使用WHERE子句來(lái)限定選擇的標(biāo)準(zhǔn)。
-- 查詢(xún)語(yǔ)句中的 WHERE 條件 select 列名稱(chēng) from 表名稱(chēng) where 列 運(yùn)算符 值 -- 更新語(yǔ)句中的 WHERE 條件 update 表名稱(chēng) set 列=新值 where 列 運(yùn)算符 值 -- 刪除語(yǔ)句中的 WHERE 條件 delete from 表名稱(chēng) where 列 運(yùn)算符 值
下面的運(yùn)算符可在 WHERE 子句中使用,用來(lái)限定選擇標(biāo)準(zhǔn):
操作符 | 描述 |
---|---|
= | 等于 |
<>(在某些版本的SQL中可以寫(xiě)為 != ) | 不等于 |
> | 大于 |
< | 小于 |
>= | 大于等于 |
<= | 小于等于 |
BETWEEN | 在某個(gè)范圍內(nèi) |
LIKE | 搜索某種模式 |
例如:可以通過(guò) WHERE 子句來(lái)限定 SELECT 的查詢(xún)條件:
-- 查詢(xún) status 為 1 的所有用戶 select * from users where status=1 -- 查詢(xún) id 大于 2 的所有用戶 select * from users where id>2 -- 查詢(xún) username 不等于 admin 的所有用戶 select * from users where username<>'admin'
AND和OR
AND和OR可在WHERE子語(yǔ)句中把兩個(gè)或多個(gè)條件結(jié)合起來(lái)。
AND表示必須同時(shí)滿足多個(gè)條件,相當(dāng)于JS中的 && 運(yùn)算符
OR表示只要滿足任意一個(gè)條件即可,相當(dāng)于JS中的 || 運(yùn)算符
ORDER BY子句
order by語(yǔ)句用于根據(jù)指定的列對(duì)結(jié)果集進(jìn)行排序。order by語(yǔ)句默認(rèn)按照升序?qū)τ涗涍M(jìn)行排序,如果想按照降序?qū)τ涗涍M(jìn)行排序,可以使用 DESC 關(guān)鍵字。
COUNT(*)函數(shù)
COUNT(*)函數(shù)用于返回查詢(xún)結(jié)果的總數(shù)據(jù)條數(shù),語(yǔ)法格式如下:
使用AS為列設(shè)置別名:如果希望給查詢(xún)出來(lái)的列名設(shè)置別名,可以使用 AS 關(guān)鍵字:
在Express項(xiàng)目中操作MySQL
安裝操作MySQL數(shù)據(jù)庫(kù)的第三方模塊(mysql):
mysql模塊是托管于npm上的第三方模塊。它提供了在 Node.js項(xiàng)目中連接和操作MySQL數(shù)據(jù)庫(kù)的能力。想要在項(xiàng)目中使用它,需要先運(yùn)行如下命令,將mysql安裝為項(xiàng)目的依賴(lài)包:(注意:如果數(shù)據(jù)庫(kù)是8.0以后的,需安裝mysql2,因?yàn)?.0+版本的加密方式改變,node目前還不支持?。鞠嚓P(guān)教程推薦:nodejs視頻教程、編程教學(xué)】
# 我的數(shù)據(jù)庫(kù)是8.0+版本,安裝如下命令即可 npm install mysql2
通過(guò)mysql模塊連接到MySQL數(shù)據(jù)庫(kù):
在使用mysql模塊操作 MySQL數(shù)據(jù)庫(kù)之前,必須先對(duì) mysql模塊進(jìn)行必要的配置,主要的配置步驟如下:
// 導(dǎo)入 mysql 模塊 const mysql = require('mysql2') // 建立與MySQL數(shù)據(jù)庫(kù)的連接 const db = mysql.createPool({ host:'127.0.0.1', // 數(shù)據(jù)庫(kù)的 IP 地址 port:'3306' // 數(shù)據(jù)庫(kù)的端口號(hào) user:'root', // 登錄數(shù)據(jù)庫(kù)的賬號(hào) password:'123456', // 登錄數(shù)據(jù)庫(kù)的密碼 database:'mysql_test'// 指定要操作哪個(gè)數(shù)據(jù)庫(kù) })
通過(guò)mysql模塊執(zhí)行SQL語(yǔ)句:
調(diào)用 db.query() 函數(shù),指定要執(zhí)行的SQL語(yǔ)句,通過(guò)回調(diào)函數(shù)拿到執(zhí)行的結(jié)果:
// 導(dǎo)入 mysql 模塊 const mysql = require('mysql2') // 建立與MySQL數(shù)據(jù)庫(kù)的連接 const db = mysql.createPool({ host:'127.0.0.1', // 數(shù)據(jù)庫(kù)的 IP 地址 port:'3306', user:'root', // 登錄數(shù)據(jù)庫(kù)的賬號(hào) password:'123456', // 登錄數(shù)據(jù)庫(kù)的密碼 database:'mysql_test'// 指定要操作哪個(gè)數(shù)據(jù)庫(kù) }) // 檢測(cè) mysql 模塊能否正常執(zhí)行 db.query('select * from users',(err,results)=>{ if(err) return console.log(err.message); // 只要能打印出 [RowDataPacket {'1','1'} ]的結(jié)果,就證明數(shù)據(jù)庫(kù)連接正常 console.log(results); })
向 users 表中新增數(shù)據(jù),其中username為張三,password為123000,代碼如下:
// 向數(shù)據(jù)庫(kù)中添加數(shù)據(jù) const thing = {username:'hh',password:123000} // 待執(zhí)行的SQL語(yǔ)句,其中英文 ? 表示占位符s // const dataStr = 'insert into users (username,password) values (?,?)' // 向表中增添數(shù)據(jù)時(shí),如果數(shù)據(jù)對(duì)象的每個(gè)屬性和數(shù)據(jù)表字段一一對(duì)應(yīng),則可以通過(guò)以下方式簡(jiǎn)單快速插入語(yǔ)句 const dataStr = 'insert into users set ?' // 使用數(shù)組形式,為 ? 占位符指定具體的值 // db.query(dataStr,[thing.username,thing.password],(err,results)=>{ db.query(dataStr,thing,(err,results)=>{ if(err) return console.log(err.message); // 失敗 // 注意:如果執(zhí)行的是insert into插入語(yǔ)句,則results是一個(gè)對(duì)象 // 可以通過(guò)affectedRows屬性,來(lái)判斷是否插入數(shù)據(jù)成功 if(results.affectedRows === 1){ console.log('數(shù)據(jù)插入成功!'); } })
因?yàn)?id 具有唯一性,即使你把某條id的記錄刪掉,它的id下一條數(shù)據(jù)是用不了的,只能自增。
更新數(shù)據(jù)對(duì)象,可以通過(guò)以下方式進(jìn)行:
// 向數(shù)據(jù)庫(kù)中更新數(shù)據(jù) const thing = {id:3,username:'aaa',password:123000} // 待執(zhí)行的SQL語(yǔ)句,其中英文 ? 表示占位符s const dataStr = 'update users set username=?,password=? where id=?' // 調(diào)用db. query()執(zhí)行SQL語(yǔ)句的同時(shí),使用數(shù)組依次為占位符指定具體的值 db.query(dataStr,[thing.username,thing.password,thing.id],(err,results)=>{ if(err) return console.log(err.message); // 失敗 // 可以通過(guò)affectedRows屬性,來(lái)判斷是否更新數(shù)據(jù)成功 if(results.affectedRows === 1){ console.log('數(shù)據(jù)更新成功!'); } })
刪除數(shù)據(jù)時(shí),推薦用唯一標(biāo)識(shí) id 去刪除。
// 向數(shù)據(jù)庫(kù)中刪除數(shù)據(jù) const dataStr = 'delete from users where id=?' db.query(dataStr,4,(err,results)=>{ if(err) return console.log(err.message); // 失敗 // 可以通過(guò)affectedRows屬性,來(lái)判斷是否刪除數(shù)據(jù)成功 if(results.affectedRows === 1){ console.log('數(shù)據(jù)刪除成功!'); } })
標(biāo)記刪除:使用DELETE語(yǔ)句,會(huì)把真正的把數(shù)據(jù)從表中刪除掉。為了保險(xiǎn)起見(jiàn),推薦使用標(biāo)記刪除的形式,來(lái)模擬刪除的動(dòng)作。所謂的標(biāo)記刪除,就是在表中設(shè)置類(lèi)似于status這樣的狀態(tài)字段,來(lái)標(biāo)記當(dāng)前這條數(shù)據(jù)是否被刪除。當(dāng)用戶執(zhí)行了刪除的動(dòng)作時(shí),我們并沒(méi)有執(zhí)行DELETE語(yǔ)句把數(shù)據(jù)刪除掉,而是執(zhí)行了UPDATE語(yǔ)句,將這條數(shù)據(jù)對(duì)應(yīng)的status字段標(biāo)記為刪除即可。
// 標(biāo)記刪除:使用 update 語(yǔ)句來(lái)替代 delete 語(yǔ)句,只更新數(shù)據(jù)的狀態(tài),并沒(méi)有真正刪除 const dataStr = 'update users set status=1 where id=?' db.query(dataStr,11,(err,results)=>{ if(err) return console.log(err.message); // 失敗 // 可以通過(guò)affectedRows屬性,來(lái)判斷是否刪除數(shù)據(jù)成功 if(results.affectedRows === 1){ console.log('數(shù)據(jù)刪除成功!'); } })