node.js之koa,mysql,SocketMocha
koa是一个基于Node.js的轻量级Web应用框架,它使用了async函数来改善异步流程的处理,具有易读、可扩展、易维护等特点。koa提供了丰富的中间件支持,可以方便地进行路由、错误处理、身份验证等功能的开发。
MySQL是一种关系型数据库管理系统,常用于存储和管理大量结构化数据。在Node.js中,可以使用mysql模块进行MySQL数据库的连接和操作。通过mysql模块,我们可以执行SQL语句,查询、插入、更新和删除表中的数据。
Socket.IO是一个基于Node.js的实时应用框架,它允许服务器与客户端之间进行双向通信。它采用了WebSocket协议,并提供了一些降级方案,以支持在不支持WebSocket的环境下仍能进行实时通信。
Mocha是一个功能丰富的JavaScript测试框架,用于编写和运行测试用例。它支持异步和同步测试,可以运行在Node.js环境中,也可以在浏览器上运行。Mocha提供了丰富的断言库和报告工具,使得编写和运行测试用例变得更加方便和可视化。
1-koa-介绍与安装
Koa.js 简介
Koa 是一个基于 Node.js 的下一代 web 框架,由 Express.js 的原班人马打造。它旨在提供更小、更富有表现力和更健壮的中间件系统,通过利用 ES6+ 语法特性(如 Generator 函数、异步迭代器、async/await 等)来消除回调函数的嵌套,从而简化了错误处理和中间件堆栈的编写。
Koa 并没有捆绑任何中间件,但提供了极简的核心工具集,让开发者可以构建高度可定制化的服务端应用程序。它的设计哲学是建立在一系列可链式调用的中间件之上,这些中间件能更好地控制请求生命周期,并且拥有简洁易读的 API。
安装 Koa.js
要安装 Koa,首先确保你的 Node.js 版本高于 v7.6.0,因为 Koa 需要支持 ES6 的 Promise 功能。然后,你可以在项目中使用 npm(Node Package Manager)来安装 Koa:
# 创建一个新的 Node.js 项目并初始化 package.json 文件
mkdir my-koa-app
cd my-koa-app
npm init -y
# 安装 Koa(这里以 Koa v2 为例)
npm install koa@next
# 或者,如果你想要安装稳定版的 Koa 2.x
npm install koa
# 创建 app.js 文件作为应用入口
touch app.js
创建一个简单的 Koa 应用示例:
// app.js
const Koa = require('koa');
const app = new Koa();
// 中间件示例,响应 Hello World
app.use(async ctx => {
ctx.body = 'Hello World';
});
// 启动服务器监听 3000 端口
app.listen(3000, () => {
console.log('Server is running on http://localhost:3000');
});
在这个例子中,我们引入了 Koa 模块,创建了一个新的 Koa 实例,并添加了一个中间件来处理所有进入应用的请求,这个中间件会将 “Hello World” 设置为 HTTP 响应体。最后,我们启动了 Web 服务器监听本地 3000 端口。
运行这个应用:
node app.js
现在打开浏览器访问 http://localhost:3000
,你应该能看到页面上显示 “Hello World”。
2-koa-对比express
Koa 和 Express 是 Node.js 生态中两个非常流行的后端开发框架,它们都采用了中间件的方式处理HTTP请求,但在设计理念和实现方式上有所不同。下面通过一个简单的示例来对比一下两者在中间件使用和错误处理上的差异:
Express 示例:
const express = require('express');
const app = express();
// 中间件示例:记录日志
app.use((req, res, next) => {
console.log(`Time: ${new Date()}, Method: ${req.method}, URL: ${req.originalUrl}`);
next();
});
// 处理GET请求的路由
app.get('/', (req, res) => {
res.send('Hello from Express!');
});
// 错误处理中间件
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).send('Something broke!');
});
app.listen(3000, () => {
console.log('Server is running on port 3000');
});
Koa 示例(基于 Koa v2 及其 async/await 特性):
const Koa = require('koa');
const app = new Koa();
// Koa 的中间件使用 async 函数并能利用 try/catch 进行异常捕获
app.use(async (ctx, next) => {
const start = new Date();
try {
await next(); // 调用下一个中间件
} finally {
const ms = new Date() - start;
console.log(`${ctx.method} ${ctx.url} - ${ms}ms`);
}
});
// GET 请求路由处理
app.use(async ctx => {
ctx.body = 'Hello from Koa!';
});
// 错误处理中间件,在 Koa 中可以更直接地捕获到错误,并传递下去
app.on('error', async (err, ctx) => {
console.error('Server Error:', err);
ctx.status = 500;
ctx.body = 'Something broke!';
});
app.listen(3000, () => {
console.log('Server is running on port 3000');
});
从上述例子可以看出:
- 中间件处理:Express 使用回调函数,而 Koa 则使用 async/await 结合 Promise 的方式,这让异步代码更加简洁且易于理解和调试。
-
错误处理:Express 需要在应用级别定义错误处理中间件,该中间件接收4个参数,其中
next
函数作为错误处理器调用;而在 Koa 中,中间件内部可以直接使用 try/catch 捕获异常,也可以监听全局的error
事件进行统一错误处理。
这些区别使得 Koa 在异步编程模型上更为先进,能够更好地利用 ES6+ 的新特性简化开发流程。同时,Koa 的中间件机制允许更精细的控制流程,减少了嵌套层级,增强了代码的可读性和可维护性。
3-koa-路由-1
在 Koa 中,路由通常由第三方库 koa-router 提供。下面是如何安装和使用 koa-router 的一个简单例子:
首先,需要安装 koa-router:
npm install koa-router@next --save
然后,在你的应用中引入并设置路由:
// app.js
const Koa = require('koa');
const Router = require('koa-router');
const app = new Koa();
const router = new Router();
// 定义一个简单的路由,访问 /hello 时返回 'Hello from Koa Router!'
router.get('/hello', async ctx => {
ctx.body = 'Hello from Koa Router!';
});
// 将路由中间件添加到 Koa 应用中
app.use(router.routes());
// 启动服务器监听 3000 端口
app.listen(3000, () => {
console.log('Server is running on http://localhost:3000');
});
现在如果你访问 http://localhost:3000/hello
,将会看到页面上显示 “Hello from Koa Router!”。
此外,koa-router 还支持更复杂的路由定义,例如带参数的路由:
router.get('/users/:id', async ctx => {
const id = ctx.params.id;
ctx.body = `User with ID: ${id}`;
});
在这个例子中,当你访问类似 http://localhost:3000/users/123
的 URL 时,ctx.params.id
将会是 “123”。
4-koa-路由-2
在 Koa 中,为了实现路由功能,通常会配合 koa-router
这个第三方库。以下是一个使用 koa-router
设置多个路由并处理不同 HTTP 方法的示例:
首先安装 koa-router
:
npm install koa-router --save
然后在项目中引入并创建路由器实例:
const Koa = require('koa');
const Router = require('koa-router');
const app = new Koa();
const router = new Router();
// 定义一个 GET 路由
router.get('/', ctx => {
ctx.body = 'Hello from the home page!';
});
// 定义一个 POST 路由
router.post('/api/users', async ctx => {
const user = ctx.request.body; // 假设 body-parser 已经解析了请求体
console.log('Received a new user:', user);
ctx.status = 201; // 创建成功状态码
ctx.body = { message: 'User created' };
});
// 定义带参数的动态路由
router.get('/posts/:id', async ctx => {
const postId = ctx.params.id;
// 假设此处从数据库获取文章
const post = await getPostById(postId);
ctx.body = post;
});
// 使用中间件
router.use((ctx, next) => {
console.log(`Time: ${new Date()}, Method: ${ctx.method}, URL: ${ctx.url}`);
return next();
});
// 将路由器挂载到 Koa 应用上
app.use(router.routes()).use(router.allowedMethods());
app.listen(3000, () => {
console.log('Server is running on port 3000');
});
在这个例子中:
- 我们定义了一个根路径
/
的 GET 路由,返回简单的欢迎信息。 - 定义了一个用于创建新用户的 POST 路由,位于
/api/users
。 - 定义了一个动态路由
/posts/:id
,其中:id
是一个参数占位符,可以匹配任何字符串,并可以通过ctx.params.id
访问该值。 - 添加了一个全局中间件,它会在每个路由之前执行,记录请求的时间、方法和URL。
最后,通过 app.use(router.routes())
将所有定义好的路由添加到 Koa 应用中,并启用相应的 HTTP 方法(如 HEAD、OPTIONS)的支持,以符合 RESTful 规范。
5-koa-静态资源
在 Koa 中,我们可以使用 koa-static 这个第三方库来提供静态文件服务。下面是如何安装和配置 koa-static 的一个例子:
首先,安装 koa-static:
npm install koa-static --save
然后,在你的应用中引入并设置静态资源目录:
// app.js
const Koa = require('koa');
const static = require('koa-static');
const path = require('path');
const app = new Koa();
// 设置静态资源目录为 'public',这意味着所有在这个目录下的文件都将作为静态资源提供服务
app.use(static(path.join(__dirname, 'public')));
// 可以继续添加其他中间件或路由
// 启动服务器监听 3000 端口
app.listen(3000, () => {
console.log('Server is running on http://localhost:3000');
});
假设你有一个名为 public
的目录,其中包含了一些静态文件(例如 HTML、CSS、JavaScript、图片等),当用户访问 http://localhost:3000/yourfile.html
时,如果该文件存在于 public
目录下,则会直接返回该文件内容。
例如,如果你的 public
目录下有一个 index.html
文件,那么通过浏览器访问 http://localhost:3000/index.html
将会显示这个 HTML 文件的内容。
6-koa-获取请求参数
在 Koa 中,要获取请求参数,首先需要使用 koa-bodyparser
这个中间件来解析请求体。以下是一个例子:
- 安装
koa-bodyparser
:
npm install koa-bodyparser --save
- 在 Koa 应用中引入并配置
koa-bodyparser
中间件:
const Koa = require('koa');
const bodyParser = require('koa-bodyparser');
const app = new Koa();
// 配置 body-parser 中间件
app.use(bodyParser());
// 处理 POST 请求的路由,假设用户提交了 JSON 格式的数据
app.post('/api/login', async ctx => {
// 使用 ctx.request.body 获取已解析的请求体数据
const { username, password } = ctx.request.body;
console.log(`Received login request with username: ${username} and password: ${password}`);
// 在此处处理登录逻辑...
});
// 如果是表单提交(Content-Type 为 application/x-www-form-urlencoded 或 multipart/form-data)
// ctx.request.body 也会包含相应的键值对
app.listen(3000, () => {
console.log('Server is running on port 3000');
});
在这个例子中,当客户端发送一个 POST 请求到 /api/login
路由,并附带 JSON 数据时,例如:
{
"username": "user1",
"password": "secret"
}
Koa 会自动通过 bodyParser
解析请求体,并将解析后的数据放入 ctx.request.body
对象中。因此,在上述路由处理器函数内,可以直接访问这些参数。
对于 GET 请求,参数通常位于 URL 查询字符串中,可以直接通过 ctx.request.query
获取,例如:
app.get('/search', async ctx => {
const query = ctx.request.query.q;
console.log(`Searching for: ${query}`);
// ...
});
若请求的 URL 为 http://localhost:3000/search?q=some+keywords
,则 query
的值将会是 "some keywords"
。
7-koa-ejs模板
在 Koa 中,我们可以使用 koa-views 和 ejs 这两个库来支持 EJS 模板引擎。下面是如何安装和配置它们的一个例子:
首先,安装所需依赖包:
npm install koa-views ejs --save
然后,在你的应用中引入并设置模板引擎:
// app.js
const Koa = require('koa');
const views = require('koa-views');
const path = require('path');
const app = new Koa();
// 设置视图目录以及使用的模板引擎(这里是 EJS)
app.use(views(path.join(__dirname, 'views'), { extension: 'ejs' }));
// 定义一个路由来渲染一个 EJS 模板
app.use(async ctx => {
// 渲染名为 'index' 的 EJS 模板,并传递数据给模板
await ctx.render('index', { title: 'Hello from Koa with EJS!' });
});
// 启动服务器监听 3000 端口
app.listen(3000, () => {
console.log('Server is running on http://localhost:3000');
});
现在,在 views
目录下创建一个名为 index.ejs
的文件,内容如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><%= title %></title>
</head>
<body>
<h1>Welcome to Koa with EJS!</h1>
</body>
</html>
当访问 http://localhost:3000
时,浏览器将显示一个带有标题 “Hello from Koa with EJS!” 的页面。在这个例子中,ctx.render('index', { title: '...' })
会查找 views
目录下的 index.ejs
文件,并将 { title: 'Hello from Koa with EJS!' }
对象中的属性值传递给模板进行渲染。
8-koa-cookie与session
在 Koa 中,我们可以使用 koa-session
或其他支持 Koa 的 session 库(如 koa-generic-session
)来管理和操作 cookie 与 session。以下是一个使用 koa-session2
(假设你已经安装了它)处理登录状态的简单示例:
首先安装 koa-session2
:
npm install koa-session2 --save
然后在 Koa 应用中设置和使用 session 以及 cookie:
const Koa = require('koa');
const session = require('koa-session2');
const app = new Koa();
// 配置 session 中间件
app.keys = ['some secret key']; // 必须提供密钥用于加密签名
const CONFIG = {
key: 'koa:sess', // cookie key (默认是 koa:sess)
maxAge: 86400000, // session 过期时间,单位毫秒(此处为一天)
overwrite: true, // 是否允许重写已存在的 session (默认true)
httpOnly: true, // 是否设置 HttpOnly 标志(默认true)
signed: true, // 是否对 cookie 进行签名(默认true)
};
app.use(session(CONFIG, app));
// 登录接口处理
app.post('/login', async ctx => {
const { username, password } = ctx.request.body;
// 假设进行了用户验证...
if (isValidUser(username, password)) {
// 用户验证成功,将用户信息存储到 session 中
ctx.session.user = { username };
ctx.status = 200;
ctx.body = { message: 'Login successful' };
} else {
ctx.status = 401;
ctx.body = { error: 'Invalid credentials' };
}
});
// 检查用户是否已登录
app.get('/protected', async ctx => {
if (ctx.session.user) {
// 用户已登录,返回保护内容
ctx.body = `Welcome back, ${ctx.session.user.username}!`;
} else {
// 用户未登录,返回错误消息或重定向到登录页面
ctx.status = 401;
ctx.body = 'Please login first';
}
});
app.listen(3000, () => {
console.log('Server is running on port 3000');
});
在这个例子中:
- 我们首先配置了
koa-session2
中间件,包括指定密钥、session 过期时间和 cookie 设置。 - 当用户通过 POST 请求访问
/login
接口并成功验证后,我们将用户的用户名存储在 session 中。 - 在
/protected
路由上,我们检查是否存在ctx.session.user
,如果有,则说明用户已登录,如果没有则表示用户未登录。
注意:实际应用中,还需要实现具体的用户验证逻辑,并确保安全地处理密码等敏感信息。此外,为了防止会话固定攻击,通常会在生成 session ID 后将其发送给客户端作为 cookie 的一部分,而不会直接在 session 中存储敏感数据。
9-koa-JWT
在 Koa 中,我们可以使用 koa-jwt 这个库来实现 JSON Web Tokens (JWT) 的验证。下面是如何安装和配置 koa-jwt 的一个例子:
首先,安装所需依赖包:
npm install koa-jwt jsonwebtoken --save
然后,在你的应用中引入并设置 JWT 验证中间件:
// app.js
const Koa = require('koa');
const jwt = require('jsonwebtoken');
const Router = require('koa-router');
const jwtKoa = require('koa-jwt');
const secretKey = 'your-secret-key'; // 用于签名和验证 JWT 的密钥
const app = new Koa();
const router = new Router();
// 创建一个生成 JWT 的函数
function createToken(user) {
return jwt.sign({ userId: user.id }, secretKey, { expiresIn: '1h' });
}
// 假设你有一个登录逻辑,这里简单模拟一下
router.post('/login', async ctx => {
const user = { id: 1 }; // 假设这是从数据库获取的用户信息
ctx.body = { token: createToken(user) };
});
// 设置 JWT 验证中间件
const authMiddleware = jwtKoa({ secret: secretKey });
// 只有经过 JWT 验证的请求才能访问的路由
router.get('/protected', authMiddleware, async ctx => {
ctx.body = 'You are authenticated!';
});
app.use(router.routes());
app.use(router.allowedMethods());
// 启动服务器监听 3000 端口
app.listen(3000, () => {
console.log('Server is running on http://localhost:3000');
});
在这个例子中,我们首先创建了一个用于生成 JWT 的函数 createToken
。当用户通过 /login
路由成功登录时,会返回一个包含 JWT 的响应。
然后,我们设置了 JWT 验证中间件 authMiddleware
,它会对请求头中的 Authorization
字段进行检查(通常格式为 Bearer <token>
)。只有当 JWT 验证通过时,客户端才能访问 /protected
路由。
注意:实际项目中,你需要根据用户输入的用户名和密码去验证身份,并根据验证结果签发 JWT。此外,为了安全起见,应妥善保管 secretKey,并且可能需要处理 token 过期、刷新等问题。
10-koa-文件上传
在 Koa 中处理文件上传,我们可以使用像 koa-body
或 koa-multer
这样的中间件。这里提供一个使用 koa-multer
处理文件上传的例子:
首先安装 koa-multer
:
npm install koa-multer --save
然后在 Koa 应用中设置并使用它来处理文件上传:
const Koa = require('koa');
const Router = require('@koa/router');
const multer = require('koa-multer');
// 设置 multer 配置(例如存储路径和文件名)
const upload = multer({
dest: 'uploads/', // 文件将被保存到此目录下
rename: function (fieldname, filename) {
return filename.replace(/\W+/g, '-').toLowerCase() + Date.now(); // 可以自定义文件名
},
});
const app = new Koa();
const router = new Router();
// 创建一个用于文件上传的路由
router.post('/upload', upload.single('file'), async ctx => { // 假设表单字段名为 file
if (ctx.file) {
console.log(`File uploaded successfully!`);
console.log(ctx.file); // 输出上传文件的信息
ctx.status = 200;
ctx.body = { message: 'File uploaded' };
} else {
ctx.status = 400;
ctx.body = { error: 'No file was uploaded' };
}
});
app.use(router.routes());
app.use(router.allowedMethods());
app.listen(3000, () => {
console.log('Server is running on port 3000');
});
在这个例子中:
- 我们首先配置了
koa-multer
的存储位置和文件重命名规则。 - 然后在路由处理器中,我们使用
upload.single('file')
来指明我们期望接收单个文件,并且表单字段名为 “file”。 - 当文件成功上传时,
ctx.file
将包含已上传文件的相关信息(如文件名、路径等)。 - 如果没有接收到任何文件,则返回错误消息。
前端需要提交表单时使用 enctype="multipart/form-data"
属性,并包含一个文件输入字段才能正确发送文件到这个端点。例如:
<form action="/upload" method="POST" enctype="multipart/form-data">
<input type="file" name="file">
<button type="submit">Upload File</button>
</form>
11-koa-操作MongoDB
在 Koa 中操作 MongoDB 数据库,可以使用 Mongoose 或原生的 MongoDB Node.js 驱动(如 mongodb
库)。这里是一个使用原生 MongoDB 客户端和 async/await 的例子:
首先安装 MongoDB Node.js 驱动:
npm install mongodb --save
然后创建一个封装了 MongoDB 操作的单例模式模块,例如 db.js
:
// db.js
const MongoClient = require('mongodb').MongoClient;
const config = require('./config'); // 引入配置文件
let _instance;
class DB {
constructor() {
if (!_instance) {
_instance = this;
this.client = null;
this.db = null;
}
return _instance;
}
async connect() {
if (!this.client || !this.db) {
const client = await MongoClient.connect(config.dbUrl, { useUnifiedTopology: true });
this.client = client;
this.db = client.db(config.dbName);
}
return this.db;
}
async close() {
if (this.client && this.db) {
await this.client.close();
this.client = null;
this.db = null;
}
}
async getCollection(collectionName) {
const db = await this.connect();
return db.collection(collectionName);
}
}
module.exports = new DB();
接下来,在 Koa 控制器中使用这个数据库连接类进行 CRUD 操作,比如获取所有用户列表:
// usersController.js
const Router = require('koa-router');
const db = require('./db');
const router = new Router();
router.get('/users', async ctx => {
try {
const usersCollection = await db.getCollection('users');
const users = await usersCollection.find().toArray();
ctx.body = users;
} catch (error) {
console.error(error);
ctx.status = 500;
ctx.body = { message: 'Internal Server Error' };
}
});
module.exports = router;
最后,在 Koa 主应用中注册路由:
// app.js
const Koa = require('koa');
const bodyParser = require('koa-bodyparser');
const usersRouter = require('./controllers/usersController');
const app = new Koa();
app.use(bodyParser());
app.use(usersRouter.routes());
app.use(usersRouter.allowedMethods());
app.listen(3000, () => {
console.log('Server is running on http://localhost:3000');
});
这样,在访问 /users
路由时,Koa 将从 MongoDB 中查询并返回所有的用户数据。这个例子展示了如何在一个简单的场景下封装 MongoDB 连接并在 Koa 中进行异步操作。
12-MySQL-介绍
MySQL 是一个开源的关系型数据库管理系统(RDBMS),由瑞典 MySQL AB 公司开发,后被 Oracle 公司收购。它以 SQL 语言为基础,广泛应用于网站和应用的后台数据存储,特别是在 LAMP(Linux、Apache、MySQL、PHP/Perl/Python)架构中扮演了重要角色。
MySQL 提供了多种数据类型支持、事务处理能力、视图、存储过程、触发器以及各种安全措施,能够高效地处理大量数据,并支持高并发读写操作。其特点是性能稳定、可扩展性好、成本低廉且易于管理。
以下是一个简单的 MySQL 示例,创建一个名为 students
的表并插入一些数据:
-- 创建 students 表
CREATE TABLE students (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
age TINYINT UNSIGNED,
gender ENUM('Male', 'Female'),
major VARCHAR(50),
enrollment_date DATE
);
-- 插入示例数据
INSERT INTO students (name, age, gender, major, enrollment_date)
VALUES ('John Doe', 20, 'Male', 'Computer Science', '2020-09-01'),
('Jane Smith', 19, 'Female', 'Mathematics', '2021-01-15');
-- 查询所有学生信息
SELECT * FROM students;
在这个例子中,我们定义了一个包含 ID(自动递增主键)、姓名、年龄、性别(使用枚举类型)、专业和入学日期字段的 students
表。接着,我们向该表中插入了两条记录,最后通过 SELECT 语句查询出表中的所有数据。
13-MySQL-sql语句-1
MySQL SQL 语句的例子非常多,这里给出一个基础的 SQL 查询示例:
假设有一个名为 employees
的表,其结构如下:
CREATE TABLE employees (
id INT PRIMARY KEY AUTO_INCREMENT,
first_name VARCHAR(50),
last_name VARCHAR(50),
job_title VARCHAR(100),
hire_date DATE
);
这个表存储了公司员工的信息。现在,我们想要执行以下几种常见的 SQL 操作:
-
插入数据:
INSERT INTO employees (first_name, last_name, job_title, hire_date) VALUES ('John', 'Doe', 'Software Engineer', '2023-01-01');
-
查询所有员工信息:
SELECT * FROM employees;
-
根据姓氏查找员工:
SELECT * FROM employees WHERE last_name = 'Doe';
-
更新某个员工的工作职位:
UPDATE employees SET job_title = 'Senior Software Engineer' WHERE id = 1;
-
删除某个员工记录(谨慎操作):
DELETE FROM employees WHERE id = 1;
-
计算员工总数:
SELECT COUNT(*) AS total_employees FROM employees;
-
按入职日期排序并获取最近入职的前5名员工:
SELECT * FROM employees ORDER BY hire_date DESC LIMIT 5;
以上这些例子展示了 MySQL 中的基本数据操作,包括数据的插入、查询、更新、删除以及统计等操作。
14-MySQL-sql语句-2
当然,这里提供另一个 MySQL SQL 语句的例子,这次展示如何更新和删除数据:
更新(UPDATE)示例:
假设我们有一个名为 employees
的表,并且想要更新某个员工的薪水。
-- 更新 employees 表中 id 为 1001 的员工的薪水
UPDATE employees
SET salary = 50000
WHERE id = 1001;
在这个例子中,SQL 语句 UPDATE employees SET salary = 50000 WHERE id = 1001;
将 employees
表中 ID 为 1001 的员工的薪水字段 (salary
) 更新为 50000。
删除(DELETE)示例:
如果我们想从 employees
表中删除一个特定的员工记录:
-- 删除 employees 表中 id 为 1002 的员工记录
DELETE FROM employees
WHERE id = 1002;
这个 DELETE FROM employees WHERE id = 1002;
语句将从 employees
表中永久性地删除 ID 为 1002 的员工的所有信息。
请注意,在实际操作数据库时,对 UPDATE 和 DELETE 操作需格外谨慎,因为它们会直接修改或删除数据。通常建议在执行这些操作前先备份数据或者使用事务来确保操作的安全性和一致性。
15-MySQL-nodejs操作-1
在 Node.js 中操作 MySQL 数据库,可以使用 mysql2 这个库,它是一个针对 Node.js 的 MySQL 客户端,支持 Promise 和 async/await。以下是如何安装和使用 mysql2 来执行基本的数据库操作(如连接数据库、查询数据)的例子:
首先,通过 npm 安装 mysql2 库:
npm install mysql2 --save
然后创建一个名为 db.js
的文件来封装数据库连接及基本操作:
// db.js
const mysql = require('mysql2/promise');
// 数据库连接配置
const config = {
host: 'localhost',
user: 'your_username',
password: 'your_password',
database: 'your_database'
};
let connection;
async function connect() {
if (!connection) {
connection = await mysql.createConnection(config);
}
return connection;
}
async function query(sql, values) {
const conn = await connect();
const [rows] = await conn.query(sql, values);
return rows;
}
async function close() {
if (connection) {
await connection.end();
connection = null;
}
}
module.exports = { query, close };
// 示例:查询所有用户
(async () => {
try {
const users = await query('SELECT * FROM users');
console.log(users);
} catch (error) {
console.error(error);
} finally {
// 在应用退出时关闭数据库连接(可选)
await close();
}
})();
接下来,在其他地方调用这个模块来进行数据库查询:
// 使用示例
const { query } = require('./db');
// 查询所有用户
async function getUsers() {
try {
const result = await query('SELECT * FROM users');
return result;
} catch (error) {
throw new Error(`Failed to fetch users: ${error.message}`);
}
}
getUsers().then(users => {
console.log('All users:', users);
}).catch(err => {
console.error('Error fetching users:', err);
});
在这个例子中,我们首先导入了 mysql2 库,并定义了一个配置对象来存储数据库连接信息。然后我们编写了三个函数:connect()
用于建立数据库连接,query()
用于执行 SQL 查询并返回结果,以及 close()
用于关闭数据库连接。
getUsers()
函数就是一个实际使用的示例,它调用了 query()
方法执行 SQL 查询语句,并处理返回的结果或错误。
16-MySQL-nodejs操作-2
在 Node.js 中操作 MySQL 数据库,我们可以使用 mysql2
这个流行的库。以下是一个基本的连接数据库、执行查询和处理结果的示例:
首先安装 mysql2
:
npm install mysql2
然后在 Node.js 应用中使用它:
const mysql = require('mysql2');
// 创建数据库连接配置
const connectionConfig = {
host: 'localhost',
user: 'your_username',
password: 'your_password',
database: 'your_database_name',
port: 3306, // 默认 MySQL 端口
};
// 建立数据库连接
const connection = mysql.createConnection(connectionConfig);
// 连接错误处理
connection.connect((err) => {
if (err) {
console.error('Error connecting to MySQL:', err);
return;
}
console.log('Connected to the MySQL server.');
// 执行一个简单的 SQL 查询
const sqlQuery = 'SELECT * FROM employees WHERE last_name = ?';
const values = ['Doe'];
connection.query(sqlQuery, values, (error, results, fields) => {
if (error) {
throw error;
}
// 处理查询结果
console.log('Employees with last name Doe:');
results.forEach(employee => {
console.log(employee);
});
// 关闭数据库连接
connection.end(err => {
if (err) {
console.error('Error closing connection:', err);
} else {
console.log('MySQL connection closed successfully.');
}
});
});
});
在这个例子中:
- 首先导入了
mysql2
库并创建了一个数据库连接配置对象。 - 使用配置信息连接到 MySQL 服务器,并在连接成功时输出提示信息。
- 编写一个 SQL 查询语句来从
employees
表中选择姓氏为 “Doe” 的所有员工记录。 - 使用
connection.query()
方法执行查询,并传递查询字符串、参数数组和回调函数。 - 在回调函数中处理查询结果,将所有找到的员工记录打印到控制台。
- 最后关闭数据库连接。
请确保替换上述代码中的 'your_username'
、'your_password'
和 'your_database_name'
为您实际的数据库凭据。
17-Socket-介绍
Socket(套接字)是一种在计算机网络中实现进程间通信的机制,特别是在TCP/IP协议簇下。它允许两个应用在互联网上进行双向、持续的数据交换。Socket编程是构建客户端-服务器架构的基础,支持实时数据传输和交互式通讯。
以下是一个简单的Socket编程示例,展示如何在Python中创建一个基于TCP的Echo服务器与客户端:
Python TCP Echo 服务器:
import socket
# 创建一个socket对象
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 绑定端口到指定地址
server_socket.bind(('localhost', 12345))
# 开始监听连接请求
server_socket.listen(5)
while True:
# 接受客户端连接
client_socket, address = server_socket.accept()
print(f"Accepted connection from {address[0]}:{address[1]}")
message = client_socket.recv(1024).decode('utf-8')
print(f"Received: {message}")
# 发送回显消息给客户端
client_socket.send(message.encode('utf-8'))
# 关闭当前客户端连接
client_socket.close()
# 在所有客户端连接处理完后关闭服务器端口
server_socket.close()
Python TCP Echo 客户端:
import socket
# 创建一个socket对象
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 连接到服务器
client_socket.connect(('localhost', 12345))
# 发送一条消息给服务器
message = "Hello, Server!"
client_socket.send(message.encode('utf-8'))
# 接收服务器回传的消息
echo_message = client_socket.recv(1024).decode('utf-8')
print(f"Received: {echo_message}")
# 关闭客户端socket
client_socket.close()
在这个例子中,服务器会接收来自任何客户端的连接,并将收到的消息原样返回给客户端。客户端则发送一条消息给服务器,然后接收并打印出服务器返回的回显消息。通过这种方式,展示了Socket编程的基本使用场景。
18-Socket-ws模块-1
以下是一个使用 Node.js 中的 ws
模块创建 WebSocket 服务端和客户端实例的基本代码示例:
服务端(server.js):
const WebSocket = require('ws');
// 创建 WebSocket 服务器实例
const wss = new WebSocket.Server({ port: 8080 });
// 监听 connection 事件,当有新连接时触发
wss.on('connection', (ws) => {
console.log('New client connected!');
// 当接收到客户端的消息时触发 message 事件
ws.on('message', (message) => {
console.log(`Received message => ${message}`);
// 将消息回传给发送它的客户端
ws.send(`Echo: ${message}`);
});
// 监听关闭事件,当连接关闭时触发
ws.on('close', () => {
console.log('Client disconnected');
});
});
console.log('WebSocket server is listening on port 8080');
客户端(client.js):
const WebSocket = require('ws');
// 连接到 WebSocket 服务器
const ws = new WebSocket('ws://localhost:8080');
// 连接建立后触发 open 事件
ws.on('open', () => {
console.log('Connected to the server!');
// 向服务器发送一条消息
ws.send('Hello from the client!');
});
// 接收从服务器发来的消息
ws.on('message', (message) => {
console.log(`Received message => ${message}`);
});
// 监听关闭事件,当连接关闭时触发
ws.on('close', () => {
console.log('Disconnected from the server');
});
// 如果在连接过程中发生错误
ws.on('error', (err) => {
console.error('Error occurred:', err);
});
在这个例子中:
- 服务端监听 8080 端口等待客户端连接。
- 当客户端与服务器建立连接后,它可以发送消息给服务器,服务器将接收并回显该消息。
- 当连接关闭时,两端都会触发 close 事件。
为了运行此示例,请确保在同一台机器上或允许网络访问的情况下同时启动服务端和客户端。
19-Socket-ws模块-2
WebSocket 是一个在单个TCP连接上进行全双工通信的协议,它允许客户端和服务器之间进行实时、双向的数据传输。Node.js 中可以使用 ws
这个库来实现 WebSocket 服务端功能。
以下是一个使用 Node.js 和 ws 模块创建 WebSocket 服务器及客户端交互的例子:
1. 创建 WebSocket 服务器(server.js):
const WebSocket = require('ws');
// 创建 WebSocket 服务器实例
const wss = new WebSocket.Server({ port: 8080 });
// 当有客户端连接时触发事件
wss.on('connection', (ws) => {
console.log('New client connected!');
// 当收到客户端的消息时处理
ws.on('message', (message) => {
console.log(`Received message => ${message}`);
// 将消息回传给客户端
ws.send(`Server received your message: ${message}`);
});
// 当客户端断开连接时触发事件
ws.on('close', () => {
console.log('Client disconnected');
});
});
2. 创建 WebSocket 客户端(client.js):
const WebSocket = require('ws');
// 创建 WebSocket 客户端对象
const ws = new WebSocket('ws://localhost:8080');
// 当连接成功建立时触发事件
ws.on('open', function open() {
console.log('Connected to server!');
// 发送一条消息给服务器
ws.send('Hello from the client!');
});
// 当接收到服务器的消息时触发事件
ws.on('message', (message) => {
console.log(`Received message => ${message}`);
});
// 当连接关闭时触发事件
ws.on('close', () => {
console.log('Connection closed');
});
// 错误处理
ws.on('error', (err) => {
console.error('Error occurred:', err);
});
在这个例子中,当客户端通过 ws://localhost:8080
连接到服务器时,会发送一条消息 “Hello from the client!”。服务器接收到该消息后,在控制台打印出来,并将一条回应消息发回给客户端。客户端收到服务器的回复后同样打印出来。
20-Socket-ws模块-3
服务端(server.js):实现广播功能
const WebSocket = require('ws');
// 创建一个 WebSocket 服务器实例,监听指定的端口
const wss = new WebSocket.Server({ port: 8080 });
// 定义在线用户列表
const clients = new Set();
// 当有新的客户端连接时触发 connection 事件
wss.on('connection', (ws) => {
console.log('New client connected!');
// 将新连接的客户端添加到在线用户列表中
clients.add(ws);
// 当从客户端接收到消息时触发 message 事件
ws.on('message', (message) => {
console.log(`Received message: ${message}`);
// 广播消息给所有在线用户(除了发送者自己)
for (const client of clients) {
if (client !== ws && client.readyState === WebSocket.OPEN) {
client.send(`Broadcast from another user: ${message}`);
}
}
});
// 当客户端断开连接时触发 close 事件
ws.on('close', () => {
console.log('Client disconnected');
// 从在线用户列表中移除已断开连接的客户端
clients.delete(ws);
});
});
console.log('WebSocket server is listening on port 8080');
客户端(client.js):简单聊天室功能
const WebSocket = require('ws');
// 创建一个 WebSocket 客户端实例,并连接到服务器
const ws = new WebSocket('ws://localhost:8080');
// 连接成功后触发 open 事件
ws.on('open', () => {
console.log('Connected to the server!');
// 注册输入监听器,当用户在控制台输入并按回车键时发送消息
process.stdin.on('data', (data) => {
const message = data.toString().trim();
if (message) {
ws.send(message);
}
});
});
// 接收来自服务器的消息
ws.on('message', (message) => {
console.log(`Message from server or other user: ${message}`);
});
// 监听关闭事件
ws.on('close', () => {
console.log('Disconnected from the server');
});
// 错误处理
ws.on('error', (err) => {
console.error('Error occurred:', err);
});
在这个例子中:
- 服务端维护了一个在线用户集合,并在接收到客户端发来的消息时,将该消息广播给所有在线用户。
- 客户端连接到服务器后,监听标准输入,当用户在终端输入信息并按下回车键时,将信息通过 WebSocket 发送给服务器。
- 所有在线用户都会接收到服务器转发的其他用户发送的消息。
21-Socket-socketio模块-1
Socket.IO 是一个基于 WebSocket 的实时通信库,它在不支持 WebSocket 的浏览器中会退化为使用轮询、长轮询或者 Flash 等技术,确保了跨平台的兼容性。以下是一个使用 Node.js 和 socket.io 模块创建服务器和客户端交互的例子:
1. 创建 Socket.IO 服务器 (server.js):
const express = require('express'); // 使用 Express 作为 HTTP 服务器
const http = require('http');
const socketIO = require('socket.io');
// 创建 Express 应用并绑定到 HTTP 服务器
const app = express();
const server = http.createServer(app);
const io = socketIO(server);
// 当有客户端连接时触发事件
io.on('connection', (socket) => {
console.log('A client has connected!');
// 接收客户端发送的消息
socket.on('chat message', (msg) => {
console.log(`Message: ${msg}`);
// 广播消息给所有已连接的客户端
io.emit('chat message', `Server received: ${msg}`);
});
// 当客户端断开连接时触发事件
socket.on('disconnect', () => {
console.log('Client disconnected');
});
});
// 启动 HTTP 服务器,并监听指定端口
server.listen(3000, () => {
console.log('Server listening on port 3000');
});
2. 创建 Socket.IO 客户端 (client.js 或者在 HTML 页面中的 JavaScript 部分):
// 在 HTML 文件中引入 socket.io 客户端库
<script src="/socket.io/socket.io.js"></script>
<script>
const socket = io('http://localhost:3000');
// 连接成功后执行的操作
socket.on('connect', function() {
console.log('Connected to the server!');
// 发送一条聊天消息给服务器
socket.emit('chat message', 'Hello from the client!');
});
// 监听从服务器广播过来的聊天消息
socket.on('chat message', function(msg) {
console.log('Received:', msg);
// 可以在此处更新 UI 显示新消息
});
// 断线重连等其他处理逻辑
</script>
在这个例子中,当客户端连接到服务器时,会发送一条消息 “Hello from the client!”。服务器收到这条消息后,在控制台打印出来,并将一条回应消息通过 io.emit
广播给所有已连接的客户端,客户端收到回复后也会在控制台打印出来。
22-Socket-socketio模块-2
使用 Socket.IO 实现服务端和客户端通信的示例
服务端(server.js)
const express = require('express');
const http = require('http');
const { Server } = require('socket.io');
// 创建 Express 应用
const app = express();
const server = http.createServer(app);
const io = new Server(server);
io.on('connection', (socket) => {
console.log('A client connected!');
// 监听来自客户端的消息事件
socket.on('message', (msg) => {
console.log(`Received message: ${msg}`);
// 广播消息给所有连接的客户端
io.emit('broadcast', `Message from user: ${msg}`);
});
// 当客户端断开连接时触发 disconnect 事件
socket.on('disconnect', () => {
console.log('Client disconnected');
});
});
// 设置 Express 服务器监听指定端口
server.listen(3000, () => {
console.log('Server is running on port 3000');
});
客户端(client.js)
// 引入 Socket.IO 客户端库
const io = require('socket.io-client');
// 连接到服务器
const socket = io('http://localhost:3000');
// 连接成功后触发 connect 事件
socket.on('connect', () => {
console.log('Connected to the server!');
// 注册键盘输入监听,当用户按下回车键时发送消息
process.stdin.on('data', (data) => {
const message = data.toString().trim();
if (message) {
socket.emit('message', message); // 发送消息到服务器
}
});
// 监听来自服务器的广播事件
socket.on('broadcast', (msg) => {
console.log(`Message received: ${msg}`);
});
// 断开连接时触发 disconnect 事件
socket.on('disconnect', () => {
console.log('Disconnected from the server');
});
});
// 错误处理
socket.on('error', (err) => {
console.error('Socket error:', err);
});
在这个例子中:
- 服务端使用了 Socket.IO 模块创建了一个 WebSocket 服务器,并在有新的客户端连接时监听其
connection
事件。 - 客户端也通过 Socket.IO 连接到服务器,并在建立连接后开始监听用户的输入并将其作为消息发送给服务器。
- 当服务器收到客户端的消息时,它会广播该消息给所有已连接的客户端。
- 无论是服务端还是客户端,在连接建立、断开或出现错误时都有相应的事件处理器进行处理。
23-Mocha-编写测试
Mocha 是一个流行的 JavaScript 测试框架,可以用于 Node.js 和浏览器环境。以下是一个使用 Mocha 编写测试的例子:
首先,确保已安装 Mocha 和 Chai(一个常用的断言库):
npm install --save-dev mocha chai
然后在项目中创建一个测试文件 test/math.spec.js
:
const { expect } = require('chai');
// 被测试的模块
const mathModule = require('../src/math'); // 假设有一个 math.js 模块
describe('Math Module', () => {
describe('#add()', () => {
it('should add two numbers correctly', () => {
const result = mathModule.add(2, 3);
expect(result).to.equal(5);
});
it('should handle non-numeric input by throwing an error', () => {
expect(() => mathModule.add('a', 2)).to.throw(TypeError);
});
});
describe('#subtract()', () => {
it('should subtract the second number from the first one', () => {
const result = mathModule.subtract(5, 3);
expect(result).to.equal(2);
});
});
});
在这个例子中,我们为一个假设存在的 math
模块编写了测试用例。#add()
方法有两组测试:一组验证正常情况下两个数相加的结果是否正确,另一组则检查传入非数字参数时是否会抛出错误。#subtract()
方法也有一个测试用例来验证减法操作。
接下来,在项目的根目录下创建一个 test
命令到 package.json
的 scripts
部分,以便运行 Mocha 测试:
{
"name": "your-project",
"scripts": {
"test": "mocha"
},
"devDependencies": {
"chai": "^4.3.4",
"mocha": "^8.3.0"
}
}
现在你可以通过运行 npm test
来执行测试:
npm test
如果一切配置正确,Mocha 将会运行你在 test/
目录下的所有 .spec.js
或 .test.js
结尾的测试文件,并输出测试结果。
24-Mocha-chai断言库
Mocha 是一个流行的 JavaScript 测试框架,而 Chai 是一个用于编写可读性更强的断言库。下面是一个使用 Mocha 和 Chai 断言库进行测试的例子:
首先安装 Mocha 和 Chai:
npm install --save-dev mocha chai
然后创建一个简单的待测试模块(例如:math.js):
// math.js
module.exports = {
add: function(a, b) {
return a + b;
},
};
接下来编写测试用例(test/math.test.js):
const assert = require('chai').assert;
const math = require('../math');
describe('Math Functions', () => {
describe('#add()', () => {
it('should correctly add two numbers', () => {
const result = math.add(2, 3);
// 使用 Chai 的断言方法进行测试
assert.equal(result, 5, '2 + 3 should equal 5');
});
it('should handle negative numbers', () => {
const result = math.add(-1, -2);
assert.equal(result, -3, '-1 + -2 should equal -3');
});
});
});
最后在命令行中运行 Mocha 测试:
npx mocha test/math.test.js
在这个例子中,我们定义了一个 math
模块并导出了一个 add
函数。接着,我们在 Mocha 测试文件中导入了这个模块,并通过 Chai 的 assert
对象对其进行了测试。每个测试用例都包含在一个 it
函数中,描述了该测试的目的。断言部分使用了 Chai 的 equal
方法来验证函数的实际返回值是否与预期相符。
25-Mocha-异步测试
在 Mocha 中进行异步测试时,可以使用回调函数、返回 Promise 或使用 async/await 语法。以下是一个使用 Promise 和 async/await 编写的异步测试示例:
使用 Promise 的异步测试
const { expect } = require('chai');
const someAsyncFunction = require('../src/someAsyncFunction'); // 假设有一个异步函数
describe('Some Async Function', function () {
it('should resolve with the expected data after an asynchronous operation', function (done) {
someAsyncFunction()
.then(data => {
expect(data).to.equal('expected value');
done();
})
.catch(done); // 如果发生错误,调用 done 来结束测试并标记为失败
});
});
使用 async/await 的异步测试
const { expect } = require('chai');
const someAsyncFunction = require('../src/someAsyncFunction'); // 同样假设有一个异步函数
describe('Some Async Function', function () {
it('should resolve with the expected data after an asynchronous operation (using async/await)', async function () {
try {
const data = await someAsyncFunction();
expect(data).to.equal('expected value');
} catch (error) {
throw error; // 或者直接 return expect().to.throw(...) 来测试预期的异常
}
});
});
// 注意:Mocha v6 及更高版本会自动处理 async 函数内部抛出的错误,无需显式地捕获和调用 `done` 函数。
在这个例子中,someAsyncFunction()
是一个返回 Promise 的异步函数。当使用 async/await 时,我们可以更自然地写出看起来像是同步代码的异步测试逻辑,而 Mocha 将会等待该 async 函数完成其异步操作后再继续执行下一个测试或判断断言是否通过。如果出现异常或者断言失败,测试将会标记为失败。
26-Mocha-http测试
在 Mocha 中进行 HTTP 接口测试时,通常会结合 supertest
库来发送 HTTP 请求并验证响应。下面是一个使用 Mocha 和 supertest 进行 HTTP 测试的例子:
首先安装所需依赖:
npm install --save-dev mocha supertest
假设我们有一个基于 Express 的简单应用(app.js):
const express = require('express');
const app = express();
app.get('/api/users/:id', (req, res) => {
const id = req.params.id;
// 假设这里是从数据库获取用户数据的逻辑,这里简化为直接返回一个对象
const user = { id: id, name: `User ${id}` };
res.json(user);
});
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => console.log(`Server is running on port ${PORT}`));
接下来编写针对这个 API 的 Mocha 测试用例(test/app.test.js):
const request = require('supertest');
const app = require('../app');
describe('GET /api/users/:id', () => {
it('should return a user with the given ID', async () => {
const response = await request(app).get('/api/users/1');
// 使用 Chai 断言库来验证响应状态码和内容
const expectedUser = { id: '1', name: 'User 1' };
expect(response.status).to.equal(200); // 使用Chai的expect风格断言
expect(response.body).to.deep.equal(expectedUser);
});
it('should return a 404 for non-existent users', async () => {
const response = await request(app).get('/api/users/999');
expect(response.status).to.equal(404);
});
});
然后运行测试:
npx mocha test/app.test.js
在这个例子中,我们使用了 supertest 发送 GET 请求到 /api/users/:id
路由,并通过 Mocha 的测试用例对响应的状态码和 JSON 内容进行了验证。如果实际应用中的路由处理程序能够正确响应这些请求,那么这些测试将会通过。
27-Mocha-钩子函数
Mocha 提供了多种钩子函数,用于在测试前后执行特定的初始化和清理操作。以下是一个使用 Mocha 钩子函数的例子:
const { expect } = require('chai');
describe('User Management Suite', function() {
let dbConnection; // 假设这是数据库连接对象
// 在整个描述块(suite)开始之前运行一次
before(function() {
console.log('Before all tests in this suite');
// 连接到数据库
return new Promise((resolve, reject) => {
dbConnection = connectToDatabase();
dbConnection.then(resolve, reject);
});
});
// 在每个测试用例(test case)之前运行一次
beforeEach(function() {
console.log('Before each test case');
// 清空用户表
return dbConnection.clearUsersTable();
});
// 测试用例
it('should create a new user', async function() {
const newUser = await createUser(dbConnection, 'John Doe', 'john@example.com');
// 断言新用户已创建
expect(newUser.name).to.equal('John Doe');
expect(newUser.email).to.equal('john@example.com');
});
it('should update an existing user', async function() {
// 假设我们已经有了一个名为 Jane 的用户
const updatedUser = await updateUser(dbConnection, 'Jane Doe', 'jane.doe@example.com', 'New Jane');
// 断言用户信息已被更新
expect(updatedUser.name).to.equal('New Jane');
expect(updatedUser.email).to.equal('jane.doe@example.com');
});
// 在每个测试用例之后运行一次
afterEach(function() {
console.log('After each test case');
// 可以在这里进行一些清理工作,比如撤销临时更改等
});
// 在整个描述块结束后运行一次
after(function() {
console.log('After all tests in this suite');
// 关闭数据库连接
return dbConnection.close();
});
});
在这个例子中:
-
before
钩子在所有测试用例执行前仅运行一次,用于初始化资源,如连接到数据库。 -
beforeEach
钩子在每个测试用例开始前都会运行,用于清空用户表或做其他准备工作。 -
it
定义了具体的测试用例。 -
afterEach
钩子在每个测试用例完成后运行,可以用来恢复环境状态或者记录测试结果。 -
after
钩子在整个描述块的所有测试用例执行完毕后运行,用于释放资源,如关闭数据库连接。
最后求点赞,求分享,求抱抱…