Node.js 程式連線
以下以 Node.js 常用的 `mysql2` 套件為例,說明如何連線 MySQL、執行 SQL,以及取得查詢結果。
## 1. 安裝 MySQL 套件
在 Node.js 專案目錄執行:
```bash
npm install mysql2
```
`mysql2` 支援 Promise 與 `async/await`,使用上較方便。
---
## 2. 建立資料庫連線
### 單一連線範例
```javascript
const mysql = require('mysql2/promise');
async function main() {
let connection;
try {
connection = await mysql.createConnection({
host: 'localhost',
port: 3306,
user: 'root',
password: 'your_password',
database: 'testdb',
charset: 'utf8mb4'
});
console.log('成功連線到 MySQL');
} catch (error) {
console.error('連線失敗:', error.message);
} finally {
if (connection) {
await connection.end();
}
}
}
main();
```
連線參數說明:
| 參數 | 說明 |
|---|---|
| `host` | MySQL 主機位置,例如 `localhost` |
| `port` | MySQL 通訊埠,預設為 `3306` |
| `user` | MySQL 使用者名稱 |
| `password` | MySQL 密碼 |
| `database` | 要使用的資料庫 |
| `charset` | 字元編碼,通常使用 `utf8mb4` |
---
## 3. 執行 SQL 指令
可以使用 `connection.execute()` 執行 SQL。
假設資料表如下:
```sql
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
email VARCHAR(200) NOT NULL
);
```
### 新增資料
```javascript
const mysql = require('mysql2/promise');
async function addUser() {
const connection = await mysql.createConnection({
host: 'localhost',
user: 'root',
password: 'your_password',
database: 'testdb'
});
try {
const sql = `
INSERT INTO users (name, email)
VALUES (?, ?)
`;
const [result] = await connection.execute(sql, [
'王小明',
'ming@example.com'
]);
console.log('新增成功');
console.log('新資料的 ID:', result.insertId);
console.log('影響筆數:', result.affectedRows);
} catch (error) {
console.error('SQL 執行失敗:', error.message);
} finally {
await connection.end();
}
}
addUser();
```
其中 `?` 是參數佔位符,實際值放在陣列中:
```javascript
await connection.execute(
'INSERT INTO users (name, email) VALUES (?, ?)',
['王小明', 'ming@example.com']
);
```
這種方式可以避免直接串接字串所造成的 SQL Injection。
---
## 4. 查詢並取得資料
### 查詢所有資料
```javascript
const mysql = require('mysql2/promise');
async function getUsers() {
const connection = await mysql.createConnection({
host: 'localhost',
user: 'root',
password: 'your_password',
database: 'testdb'
});
try {
const [rows] = await connection.execute(
'SELECT id, name, email FROM users'
);
console.log(rows);
for (const user of rows) {
console.log(
`ID:${user.id},姓名:${user.name},Email:${user.email}`
);
}
} catch (error) {
console.error('查詢失敗:', error.message);
} finally {
await connection.end();
}
}
getUsers();
```
`rows` 通常會是一個 JavaScript 陣列:
```javascript
[
{
id: 1,
name: '王小明',
email: 'ming@example.com'
},
{
id: 2,
name: '李小華',
email: 'hua@example.com'
}
]
```
---
### 使用條件查詢
```javascript
async function getUserById(id) {
const connection = await mysql.createConnection({
host: 'localhost',
user: 'root',
password: 'your_password',
database: 'testdb'
});
try {
const [rows] = await connection.execute(
'SELECT * FROM users WHERE id = ?',
[id]
);
if (rows.length === 0) {
console.log('找不到資料');
return null;
}
console.log('查詢結果:', rows[0]);
return rows[0];
} finally {
await connection.end();
}
}
getUserById(1);
```
---
## 5. 更新資料
```javascript
const [result] = await connection.execute(
'UPDATE users SET email = ? WHERE id = ?',
['new@example.com', 1]
);
console.log('更新筆數:', result.affectedRows);
```
完整例子:
```javascript
async function updateUser(id, email) {
const connection = await mysql.createConnection({
host: 'localhost',
user: 'root',
password: 'your_password',
database: 'testdb'
});
try {
const [result] = await connection.execute(
'UPDATE users SET email = ? WHERE id = ?',
[email, id]
);
return result.affectedRows;
} finally {
await connection.end();
}
}
```
---
## 6. 刪除資料
```javascript
const [result] = await connection.execute(
'DELETE FROM users WHERE id = ?',
[1]
);
console.log('刪除筆數:', result.affectedRows);
```
---
## 7. 使用連線池
在 Web API 或長時間執行的伺服器中,通常不應該每次請求都重新建立連線,而應該使用 Connection Pool。
```javascript
const mysql = require('mysql2/promise');
const pool = mysql.createPool({
host: 'localhost',
port: 3306,
user: 'root',
password: 'your_password',
database: 'testdb',
waitForConnections: true,
connectionLimit: 10,
queueLimit: 0
});
async function getUsers() {
const [rows] = await pool.execute(
'SELECT id, name, email FROM users'
);
return rows;
}
async function addUser(name, email) {
const [result] = await pool.execute(
'INSERT INTO users (name, email) VALUES (?, ?)',
[name, email]
);
return result.insertId;
}
async function main() {
try {
const users = await getUsers();
console.log('使用者資料:', users);
const id = await addUser('陳大明', 'da@example.com');
console.log('新增 ID:', id);
} catch (error) {
console.error(error);
} finally {
await pool.end();
}
}
main();
```
---
## 8. 在 Express API 中使用
如果 Node.js 使用 Express,可以將查詢結果回傳為 JSON:
```bash
npm install express mysql2
```
```javascript
const express = require('express');
const mysql = require('mysql2/promise');
const app = express();
app.use(express.json());
const pool = mysql.createPool({
host: 'localhost',
user: 'root',
password: 'your_password',
database: 'testdb',
connectionLimit: 10
});
app.get('/users', async (req, res) => {
try {
const [rows] = await pool.execute(
'SELECT id, name, email FROM users'
);
res.json(rows);
} catch (error) {
console.error(error);
res.status(500).json({
error: '資料庫查詢失敗'
});
}
});
app.get('/users/:id', async (req, res) => {
try {
const [rows] = await pool.execute(
'SELECT id, name, email FROM users WHERE id = ?',
[req.params.id]
);
if (rows.length === 0) {
return res.status(404).json({
error: '找不到使用者'
});
}
res.json(rows[0]);
} catch (error) {
console.error(error);
res.status(500).json({
error: '資料庫查詢失敗'
});
}
});
app.listen(3000, () => {
console.log('伺服器啟動於 http://localhost:3000');
});
```
啟動後:
```bash
node app.js
```
瀏覽:
```text
http://localhost:3000/users
```
即可取得 JSON 格式的資料。
---
## 9. 重要注意事項
### 使用參數化查詢
不要這樣直接拼接使用者輸入:
```javascript
const sql = `SELECT * FROM users WHERE name = '${name}'`;
```
應改為:
```javascript
const [rows] = await pool.execute(
'SELECT * FROM users WHERE name = ?',
[name]
);
```
### 不要把密碼直接寫在程式碼中
可使用環境變數:
```bash
npm install dotenv
```
`.env`:
```env
DB_HOST=localhost
DB_USER=root
DB_PASSWORD=your_password
DB_NAME=testdb
```
程式:
```javascript
require('dotenv').config();
const mysql = require('mysql2/promise');
const pool = mysql.createPool({
host: process.env.DB_HOST,
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: process.env.DB_NAME
});
```
### `execute()` 回傳值
通常可以這樣解構:
```javascript
const [rows, fields] = await connection.execute(sql, params);
```
- `rows`:查詢資料,或新增、更新、刪除時的結果
- `fields`:欄位資訊
- `result.insertId`:新增資料的自動編號
- `result.affectedRows`:受影響的資料筆數
總結來說,基本流程是:
```javascript
const [rows] = await pool.execute(
'SELECT * FROM users WHERE id = ?',
[1]
);
console.log(rows);
```
也就是:
1. 安裝 `mysql2`
2. 建立連線或連線池
3. 使用 `execute()` 執行 SQL
4. 使用 `?` 與參數陣列傳入資料
5. 從 `rows` 取得查詢結果
6. 使用完畢後關閉連線池或連線
相關學習地圖、教學課程
Python 後端工程、資料庫