Hello World - HTTP 服务器.md
目标
通过 MariaDB CLI 和 Python 驱动完成数据库创建、CRUD 操作,体验 MariaDB 与 MySQL 的命令兼容性。
💡 MariaDB 的客户端命令、SQL 语法与 MySQL 完全相同,所有 MySQL 工具(mysql、mysqldump 等)均适用于 MariaDB。
环境准备
mysql -u root -p
docker exec -it mariadb-dev mysql -u root -proot123
第一步:CLI 操作
-- 创建数据库(MariaDB 独有:支持 OR REPLACE)
CREATE OR REPLACE DATABASE hello_mariadb CHARACTER SET utf8mb4;
USE hello_mariadb;
-- 创建表(体验 MariaDB CHECK 约束)
CREATE TABLE employees (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(50) NOT NULL,
department VARCHAR(50),
salary DECIMAL(10,2) CHECK(salary > 0),
hire_date DATE DEFAULT (CURRENT_DATE),
INDEX idx_dept (department)
);
-- 插入
INSERT INTO employees (name, department, salary) VALUES
('张三', '技术部', 15000.00),
('李四', '市场部', 12000.00),
('王五', '技术部', 18000.00),
('赵六', '人事部', 10000.00);
-- 查询
SELECT * FROM employees ORDER BY salary DESC;
-- MariaDB 独有:EXCEPT(差集)
SELECT department FROM employees WHERE department = '技术部';
-- 聚合
SELECT department, COUNT(*) AS cnt, AVG(salary) AS avg_sal
FROM employees
GROUP BY department
HAVING cnt >= 1
ORDER BY avg_sal DESC;
-- 窗口函数(MariaDB 10.2+ 支持)
SELECT name, department, salary,
RANK() OVER (PARTITION BY department ORDER BY salary DESC) AS dept_rank
FROM employees;
第二步:Python 操作
pip install mariadb
import mariadb
import sys
try:
conn = mariadb.connect(
host="localhost",
user="root",
password="root123",
database="hello_mariadb"
)
except mariadb.Error as e:
print(f"连接错误: {e}")
sys.exit(1)
cur = conn.cursor()
# 创建表
cur.execute("""
CREATE TABLE IF NOT EXISTS products (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
price DECIMAL(8,2) CHECK(price >= 0),
category VARCHAR(30),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
""")
# 批量插入
products = [
("机械键盘", 299.00, "外设"),
("无线鼠标", 89.00, "外设"),
("显示器", 1999.00, "显示"),
]
cur.executemany(
"INSERT INTO products (name, price, category) VALUES (?, ?, ?)",
products
)
conn.commit()
# 查询 + 参数化
cur.execute(
"SELECT name, price FROM products WHERE price > ? ORDER BY price DESC",
(100,)
)
for name, price in cur.fetchall():
print(f"{name}: ¥{price}")
# 事务
try:
cur.execute("UPDATE products SET price = price * 0.9 WHERE category = ?", ("外设",))
cur.execute("SELECT ROW_COUNT()")
updated = cur.fetchone()[0]
print(f"打折影响 {updated} 行")
conn.commit()
except:
conn.rollback()
cur.close()
conn.close()
第三步:使用 RETURNING 子句(MariaDB 独有)
-- MariaDB 10.5+ 支持 RETURNING
INSERT INTO products (name, price, category)
VALUES ('USB Hub', 49.00, '外设')
RETURNING id, name, created_at;
-- 直接返回新插入行的数据,无需再 SELECT
预期输出
# CLI 窗口函数
name | department | salary | dept_rank
-------|------------|---------|-----------
王五 | 技术部 | 18000.00| 1
张三 | 技术部 | 15000.00| 2
李四 | 市场部 | 12000.00| 1
赵六 | 人事部 | 10000.00| 1
# Python
显示器: ¥1999.00
机械键盘: ¥299.00
打折影响 2 行
异步编程 - 回调 Promise async-await.md
Node.js Hello World — HTTP 服务器
目标
用 Node.js 内置 http 模块创建一个最简单的 Web 服务器,监听 3000 端口,返回 JSON 格式的 "Hello World"。
完整代码
const http = require('http');
const hostname = '127.0.0.1';
const port = 3000;
const server = http.createServer((req, res) => {
res.statusCode = 200;
res.setHeader('Content-Type', 'application/json');
if (req.url === '/') {
res.end(JSON.stringify({ message: 'Hello World', timestamp: Date.now() }));
} else if (req.url === '/health') {
res.end(JSON.stringify({ status: 'ok' }));
} else {
res.statusCode = 404;
res.end(JSON.stringify({ error: 'Not Found' }));
}
});
server.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});
运行步骤
node server.js
curl http:
预期输出
$ node server.js
Server running at http:
访问 http://127.0.0.1:3000/ 返回:
{"message":"Hello World","timestamp":1717000000000}
要点说明
http.createServer() 创建 HTTP 服务器,传入回调处理每个请求
req.url 获取请求路径,可用于简单路由
res.setHeader() 设置响应头(JSON API 通常用 application/json)
server.listen() 绑定端口并启动,第三个参数是启动回调
01-hello-world-http-server.md
Node.js Hello World — HTTP 服务器
目标
用 Node.js 内置 http 模块创建一个最简单的 Web 服务器,监听 3000 端口,返回 JSON 格式的 "Hello World"。
完整代码
const http = require('http');
const hostname = '127.0.0.1';
const port = 3000;
const server = http.createServer((req, res) => {
res.statusCode = 200;
res.setHeader('Content-Type', 'application/json');
if (req.url === '/') {
res.end(JSON.stringify({ message: 'Hello World', timestamp: Date.now() }));
} else if (req.url === '/health') {
res.end(JSON.stringify({ status: 'ok' }));
} else {
res.statusCode = 404;
res.end(JSON.stringify({ error: 'Not Found' }));
}
});
server.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});
运行步骤
node server.js
curl http:
预期输出
$ node server.js
Server running at http:
访问 http://127.0.0.1:3000/ 返回:
{"message":"Hello World","timestamp":1717000000000}
要点说明
http.createServer() 创建 HTTP 服务器,传入回调处理每个请求
req.url 获取请求路径,可用于简单路由
res.setHeader() 设置响应头(JSON API 通常用 application/json)
server.listen() 绑定端口并启动,第三个参数是启动回调
02-express-rest-api.md
Node.js Express — RESTful API 增删改查
目标
使用 Express 框架构建一个完整的用户管理 RESTful API,实现 CRUD 操作,数据存储在内存中。
完整代码
const express = require('express');
const app = express();
const port = 3000;
app.use(express.json());
let users = [
{ id: 1, name: 'Alice', email: 'alice@example.com' },
{ id: 2, name: 'Bob', email: 'bob@example.com' },
];
let nextId = 3;
app.get('/users', (req, res) => {
res.json({ total: users.length, data: users });
});
app.get('/users/:id', (req, res) => {
const user = users.find(u => u.id === parseInt(req.params.id));
if (!user) return res.status(404).json({ error: 'User not found' });
res.json(user);
});
app.post('/users', (req, res) => {
const { name, email } = req.body;
if (!name || !email) {
return res.status(400).json({ error: 'name and email are required' });
}
const user = { id: nextId++, name, email };
users.push(user);
res.status(201).json(user);
});
app.put('/users/:id', (req, res) => {
const user = users.find(u => u.id === parseInt(req.params.id));
if (!user) return res.status(404).json({ error: 'User not found' });
const { name, email } = req.body;
if (name) user.name = name;
if (email) user.email = email;
res.json(user);
});
app.delete('/users/:id', (req, res) => {
const index = users.findIndex(u => u.id === parseInt(req.params.id));
if (index === -1) return res.status(404).json({ error: 'User not found' });
users.splice(index, 1);
res.status(204).send();
});
app.listen(port, () => {
console.log(`API server listening at http://localhost:${port}`);
});
运行步骤
npm init -y
npm install express
node app.js
测试
curl http:
curl -X POST http:
-H "Content-Type: application/json" \
-d '{"name":"Charlie","email":"charlie@example.com"}'
curl -X PUT http:
-H "Content-Type: application/json" \
-d '{"name":"Alice Updated"}'
curl -X DELETE http:
预期输出
$ node app.js
API server listening at http:
| 请求 |
响应 |
GET /users |
{"total":2,"data":[{...},{...}]} |
POST /users |
{"id":3,"name":"Charlie","email":"charlie@example.com"} |
PUT /users/1 |
{"id":1,"name":"Alice Updated","email":"alice@example.com"} |
DELETE /users/3 |
204 No Content |
要点说明
express.json() 中间件解析请求体 JSON
- RESTful 命名规范:资源复数形式(
/users),HTTP 方法表达操作
- 状态码:200 成功、201 创建成功、204 删除成功无内容、400 参数错误、404 不存在
HTTP 服务器入门 — Hello World + 文件读写.md
Node.js HTTP 服务器入门
目标
使用 Node.js 内置 http 模块和 fs 模块,创建最简单的 Web 服务器,并实现文件读写演示。
完整代码
const http = require('http');
const fs = require('fs');
const path = require('path');
const PORT = 3000;
const DATA_FILE = path.join(__dirname, 'data.json');
if (!fs.existsSync(DATA_FILE)) {
fs.writeFileSync(DATA_FILE, JSON.stringify({ visits: 0, messages: [] }, null, 2));
}
const server = http.createServer((req, res) => {
const { method, url } = req;
if (method === 'GET' && url === '/') {
const data = JSON.parse(fs.readFileSync(DATA_FILE, 'utf-8'));
data.visits++;
fs.writeFileSync(DATA_FILE, JSON.stringify(data, null, 2));
res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
res.end(`
<h1>🎉 Node.js 服务器运行中</h1>
<p>累计访问次数:<strong>${data.visits}</strong></p>
<p>消息数量:${data.messages.length}</p>
<a href="/api/messages">查看消息 API</a>
`);
}
else if (method === 'GET' && url === '/api/messages') {
const data = JSON.parse(fs.readFileSync(DATA_FILE, 'utf-8'));
res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8' });
res.end(JSON.stringify({ success: true, ...data }));
}
else if (method === 'POST' && url === '/api/messages') {
let body = '';
req.on('data', chunk => (body += chunk));
req.on('end', () => {
const data = JSON.parse(fs.readFileSync(DATA_FILE, 'utf-8'));
const { text } = JSON.parse(body);
data.messages.push({ id: Date.now(), text, time: new Date().toISOString() });
fs.writeFileSync(DATA_FILE, JSON.stringify(data, null, 2));
res.writeHead(201, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ success: true, message: '已添加' }));
});
}
else {
res.writeHead(404, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ error: 'Not Found' }));
}
});
server.listen(PORT, () => {
console.log(`🚀 服务器已启动: http://localhost:${PORT}`);
});
运行步骤
node server.js
预期输出
- 浏览器显示欢迎页,含访问计数
GET /api/messages 返回 JSON 消息列表
POST /api/messages 新增消息,data.json 文件实时更新
WebSocket 实时聊天室 — ws 库实战.md
Node.js WebSocket 实时聊天室
目标
使用 ws 库构建多人在线聊天室,演示 Node.js 的事件驱动模型在实时通信中的优势。
完整代码
const WebSocket = require('ws');
const http = require('http');
const fs = require('fs');
const path = require('path');
const server = http.createServer((req, res) => {
if (req.url === '/') {
res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
res.end(fs.readFileSync(path.join(__dirname, 'index.html'), 'utf-8'));
}
});
const wss = new WebSocket.Server({ server });
const clients = new Map(); // ws -> username
let messageHistory = []; // 保留最近 50 条
wss.on('connection', (ws, req) => {
const ip = req.socket.remoteAddress;
console.log(`🔗 新连接: ${ip}`);
ws.on('message', (raw) => {
const msg = JSON.parse(raw);
switch (msg.type) {
case 'join':
clients.set(ws, msg.username);
broadcast({ type: 'system', text: `${msg.username} 加入了聊天室`, time: now() });
broadcast({ type: 'users', users: [...clients.values()] });
ws.send(JSON.stringify({ type: 'history', messages: messageHistory }));
break;
case 'message':
const username = clients.get(ws);
if (username) {
const chatMsg = { type: 'message', username, text: msg.text, time: now() };
messageHistory.push(chatMsg);
if (messageHistory.length > 50) messageHistory.shift();
broadcast(chatMsg);
}
break;
}
});
ws.on('close', () => {
const username = clients.get(ws);
if (username) {
clients.delete(ws);
broadcast({ type: 'system', text: `${username} 离开了`, time: now() });
broadcast({ type: 'users', users: [...clients.values()] });
}
});
});
function broadcast(msg) {
const data = JSON.stringify(msg);
wss.clients.forEach((client) => {
if (client.readyState === WebSocket.OPEN) client.send(data);
});
}
function now() {
return new Date().toLocaleTimeString('zh-CN', { hour12: false });
}
server.listen(3000, () => console.log('💬 聊天室: http://localhost:3000'));
<!-- index.html -->
<!DOCTYPE html>
<html><head><meta charset="utf-8"><title>聊天室</title>
<style>
* { margin:0; padding:0; box-sizing:border-box; }
body { font-family: system-ui; max-width:600px; margin:20px auto; }
#messages { border:1px solid #ddd; height:400px; overflow-y:auto; padding:10px; }
.system { color:#999; text-align:center; margin:5px 0; }
.msg { margin:4px 0; } .msg strong { color:#2563eb; }
input,button { padding:8px; margin-top:8px; }
input { width:70%; } button { width:25%; }
</style></head><body>
<h2>💬 在线聊天室</h2>
<div id="messages"></div>
<input id="msgInput" placeholder="输入消息..." autofocus>
<button onclick="sendMsg()">发送</button>
<script>
const username = '用户' + Math.floor(Math.random()*1000);
const ws = new WebSocket(`ws://${location.host}`);
const messages = document.getElementById('messages');
const msgInput = document.getElementById('msgInput');
ws.onopen = () => ws.send(JSON.stringify({ type:'join', username }));
ws.onmessage = (e) => {
const msg = JSON.parse(e.data);
if (msg.type === 'system') {
messages.innerHTML += `<div class="system">${msg.text} <small>${msg.time}</small></div>`;
} else if (msg.type === 'message') {
messages.innerHTML += `<div class="msg"><strong>${msg.username}</strong>: ${msg.text} <small>${msg.time}</small></div>`;
}
messages.scrollTop = messages.scrollHeight;
};
function sendMsg() {
const text = msgInput.value.trim();
if (text) {
ws.send(JSON.stringify({ type:'message', text }));
msgInput.value = '';
}
}
msgInput.addEventListener('keydown', (e) => { if(e.key==='Enter') sendMsg(); });
</script></body></html>
运行步骤
npm install ws
node server.js
预期效果
- 每个窗口输入用户名后加入
- 消息实时推送给所有在线用户
- 用户离开时全网广播
- 新接入用户收到最近历史消息