Node.js Koa框架入门
1、介绍
Koa是一个由Express原班人马打造的轻量级、现代化的Node.js Web框架,旨在提供一个更小、更富有表现力且更健壮的基础。它通过创新的“洋葱模型”中间件机制和现代的async/await语法,为构建Web应用和API带来了全新的体验。

2、安装
1、新建一个文件夹 koa-demo
2、在终端下打开此文件夹
3、执行命令
npm init -y
npm install koa -S
4、在根目录下创建 index.js 文件
const Koa = require('koa');
const app = new Koa();
app.use(async (ctx)=>{
ctx.body = 'Hello Koa';
})
app.listen(4000);
5、在终端运行命令 node .\index.js 可以启动服务
6、访问http://localhost:4000
3、router使用
npm install @koa/router -S
https://www.npmjs.com/package/@koa/router
访问不同路由,展示内容不同
const Koa = require('koa');
const app = new Koa();
const Router = require('@koa/router');
const router = new Router();
router.get('/',async (ctx)=>{
ctx.body = 'Hello Koa Router';
})
router.get('/api',async (ctx)=>{
ctx.body = 'Hello Koa Router API';
})
app.use(router.routes()).use(router.allowedMethods());
app.listen(4000)
4、中间件
中间件(Middleware) 是在请求和响应处理的“管道”中执行的函数,它能够拦截进入应用的请求,执行自定义逻辑,然后再决定是将请求继续传递下去,还是直接返回响应。
先进后出
// middleware.js
const Koa = require("koa");
const app = new Koa();
const middleware1 = function async(ctx,next) {
console.log("middleware1")
}
const middleware2 = function async(ctx,next) {
console.log("middleware2");
next();
console.log("m2");
}
const middleware3 = function async(ctx,next) {
console.log("middleware3");
next();
console.log("m3");
}
app.use(middleware2);
app.use(middleware3)
app.use(middleware1)
app.listen(4000);
打印顺序:
middleware2
middleware3
middleware1
m3
m2
5、koa-generator 快速生成koa服务的脚手架
// 全局安装
npm install -g koa-generator
// koa2 + 项目名 -》搭建项目
koa2 koa-generator-project
cd .\koa-generator-project
npm install
npm run dev


6、日志
npm install log4js -D
const log4js = require('log4js');
const levels = {
trace: log4js.levels.TRACE,
debug: log4js.levels.DEBUG,
info: log4js.levels.INFO,
warn: log4js.levels.WARN,
error: log4js.levels.ERROR,
fatal: log4js.levels.FATAL
}
log4js.configure({
appenders: {
console: { type: 'console' },
info: { type: 'file', filename: 'logs/info.log' },
warn: { type: 'file', filename: 'logs/warn.log' },
error: { type: 'file', filename: 'logs/error.log' },
fatal: { type: 'file', filename: 'logs/fatal.log' },
trace: { type: 'dateFile', filename: 'logs/trace' ,pattern: 'yyyy-MM-dd.log', alwaysIncludePattern: true }
},
categories: {
default: { appenders: ['console'], level: 'debug' },
info: { appenders: ['info','console'], level: 'info' },
warn: { appenders: ['warn','console'], level: 'warn' },
error: { appenders: ['error','console'], level: 'error' },
fatal: { appenders: ['fatal','console'], level: 'fatal' },
trace: { appenders: ['trace','console'], level: 'trace' }
}
});
exports.debug = (content) => {
const logger = log4js.getLogger('debug');
logger.level = levels.debug;
logger.debug(content);
};
exports.info = (content) => {
const logger = log4js.getLogger('info');
logger.level = levels.info;
logger.info(content);
};
exports.warn = (content) => {
const logger = log4js.getLogger('warn');
logger.level = levels.warn;
logger.warn(content);
};
exports.error = (content) => {
const logger = log4js.getLogger('error');
logger.level = levels.error;
logger.error(content);
};
exports.fatal = (content) => {
const logger = log4js.getLogger('fatal');
logger.level = levels.fatal;
logger.fatal(content);
};
exports.trace = (content) => {
const logger = log4js.getLogger('trace');
logger.level = levels.trace;
logger.trace(content);
};
app.js
const log4js = require('./utils/log4');
log4js.info('app.js start...');
log4js.debug('app.js debug log');
log4js.warn('app.js warn log');
log4js.error('app.js error log');
log4js.fatal('app.js fatal log');
log4js.trace('app.js trace log');


7、MySQL安装及使用
下载地址:https://dev.mysql.com/downloads/installer/
下载完成后按照提示安装,并设置密码
配置环境变量

以管理员身份运行终端
net start MySQL版本号:启动服务
net stop MySQL版本号:停止服务
mysql -u root -p -h 127.0.0.1 :登录数据库

注意:必须加分号
输入exit可以退出登录
通过命令创建一个数据库:create database 数据库名;

项目中安装mysql包:npm install mysql --save
npm install mysql2 --save
8、sequelize
安装sequelize: npm install sequelize --save
sequelize:ORM node框架,对SQL查询语句封装,可以用OOP的方式操作数据库;
// db.js
const Sequelize = require('sequelize');
const log4js = require('./log4');
const sequelize = new Sequelize('dev5','root','Admin@123',{
host: 'localhost', // 数据库地址
dialect: 'mysql', // 指定使用 MySQL 数据库
pool: {
max: 5, // 连接池中最大连接数量
min: 0, // 连接池中最小连接数量
acquire: 30000, // 连接最长等待时间,超过这个时间就会抛出错误
idle: 10000 // 超过10秒没有操作,就会自动断开连接
}
});
sequelize.authenticate()
.then(() => {
log4js.info('数据库连接成功');
})
.catch(err => {
log4js.error('数据库连接失败:', err);
});
sequelize.sync() // 同步模型到数据库
module.exports = sequelize;
// 在app.js中引入
require("./utils/db.js");

8.1、模型(model/user)
const db = require('../utils/db');
const Sequelize = require('sequelize');
const moment = require('moment');
const user = db.define('user', {
id: {
type: Sequelize.INTEGER(11),
primaryKey: true,
autoIncrement: true
},
name: {
type: Sequelize.STRING(255),
allowNull: false
},
age: {
type: Sequelize.INTEGER,
defaultValue: 0,
},
sex: Sequelize.STRING,
birth:{
type: Sequelize.DATE,
defaultValue: Sequelize.NOW,
get() {
// 获取原始值并格式化为字符串
const rawValue = this.getDataValue('birth');
return moment(rawValue).format('YYYY-MM-DD HH:mm:ss');
}
},
createdAt: {
type: Sequelize.DATE,
defaultValue: Sequelize.NOW,
get() {
const rawValue = this.getDataValue('createdAt');
return moment(rawValue).format('YYYY-MM-DD HH:mm:ss');
}
},
updatedAt: {
type: Sequelize.DATE,
defaultValue: Sequelize.NOW,
get() {
const rawValue = this.getDataValue('updatedAt');
return moment(rawValue).format('YYYY-MM-DD HH:mm:ss');
}
},
addr: Sequelize.STRING,
},{
freezeTableName: true, // 禁止修改表名
});
module.exports = user;
8.2、控制层(controller/user)
const User = require('../model/user');
const { Op } = require('sequelize');
const log4js = require('../utils/log4');
const listAll = async(ctx) => {
log4js.info(`查询用户列表:参数-${JSON.stringify(ctx.query)};请求IP-${ctx.ip};请求路径-${ctx.path}`);
const page = parseInt(ctx.query.page) || 1; // 当前页码,默认为1
const pageSize = parseInt(ctx.query.pageSize) || 10;
const name = ctx.query.name || '';
const offset = (page - 1) * pageSize; // 计算偏移量
// 动态构建 where 条件
const whereCondition = {};
if (name) {
// 姓名模糊匹配,使用 LIKE 操作符
whereCondition.name = { [Op.like]: `%${name}%` };
}
if (ctx.query.sex) { // 性别精确匹配
whereCondition.sex = ctx.query.sex;
}
try{
// 分页查询
const result = await User.findAndCountAll({
where: whereCondition,
order: [['createdAt', 'DESC']], // 按照创建时间降序排序
limit: pageSize,
offset: offset,
logging: (sql) => log4js.info(`用户列表查询-SQL: ${sql}`)
});
ctx.body = {
code: 200,
total: result.count, // 总记录数
data: result.rows,
page,
pageSize,
message: 'success'
}
}catch(error){
log4js.error('查询用户列表失败', error);
const msg = error.errors[0]
ctx.body = {
code: 500,
message: msg.value + ' ' + msg.message
}
}
// const data = await User.findAll(); // 查询所有用户
// ctx.body = {
// code: 200,
// data
// }
}
const create = async(ctx) => {
const params = ctx.request.body;
try {
await User.create(params); // 创建用户
ctx.body = {
code: 200,
message: '用户创建成功'
}
} catch (error) {
const msg = error.errors[0]
ctx.body = {
code: 500,
message: '用户创建失败:' + msg.value + ' ' + msg.message
}
}
}
const update = async(ctx) => {
const {id,name,age,sex,birth,addr} = ctx.request.body;
try {
await User.update({name,age,sex,birth,addr},{
where: {id}
})
ctx.body = {
code: 200,
message: '用户更新成功'
}
} catch (error) {
const msg = error.errors[0]
ctx.body = {
code: 500,
message: '用户更新失败:' + msg.value + ' ' + msg.message
}
}
}
const deleteUser = async(ctx) => {
try {
const id = ctx.request.body.id;
await User.destroy({
where: { id }
});
ctx.body = {
code: 200,
message: '用户删除成功'
}
} catch (error) {
const msg = error.errors[0]
ctx.body = {
code: 500,
message: '用户删除失败:' + msg.value + ' ' + msg.message
}
}
}
module.exports = {
listAll,
create,
update,
deleteUser
}
8.3、路由(router/user)
const router = require('koa-router')()
const User = require('../controller/user');
router.prefix('/users')
router.get('/', User.listAll)
router.post('/addUser', User.create)
router.post('/updateUser', User.update)
router.post('/deleteUser', User.deleteUser)
// router.get('/', function (ctx, next) {
// ctx.body = 'this is a users response!'
// })
// router.get('/bar', function (ctx, next) {
// ctx.body = 'this is a users/bar response'
// })
module.exports = router
8.4、常用API
1)连接数据库
const sequelize = new Sequelize('database', 'username', 'password', {
host: 'localhost',
dialect: /* one of 'mysql' | 'postgres' | 'sqlite' | 'mariadb' | 'mssql' | 'db2' | 'snowflake' | 'oracle' */
});
2)测试数据库是否连接成功
sequelize.authenticate()
.then(()=>{
// 连接成功
})
.catch(()=>{
// 连接失败
})
3)模型:数据库中表的抽象
定义:
sequelize.define
同步某个表:
User.sync()
自动同步所有模型:
sequelize.sync()
删除某个表:
await User.drop();
console.log("用户表已删除!");
删除所有表:
await sequelize.drop();
console.log("所有表已删除!");
创建实例:
User.create
更新实例:
User.update
删除实例:
User.destory
使用提供的主键从表中仅获得一个条目:
findByPk
除非找到一个满足查询参数的结果,否则方法 findOrCreate 将在表中创建一个条目:
findOrCreate
分页查询:
findAndCountAll
原始查询(sql):
sequelize.query
关联:见 https://www.sequelize.cn/core-concepts/assocs
8.5、场景
1、关联模型并查询
const Sequelize = require('sequelize');
const { DataTypes } = Sequelize;
const db = new Sequelize(...); // 连接数据库
// 商品模型 (A表)
const Product = db.define('Product', {
primaryId: {
type: DataTypes.INTEGER,
primaryKey: true, // 主键
autoIncrement: true // 自增
},
name: DataTypes.STRING,
price: DataTypes.FLOAT
}, {
tableName: 'A' // 实际表名
});
// 售卖情况模型 (B表)
const Sale = sequelize.define('Sale', {
id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true
},
quantity: DataTypes.INTEGER,
saleDate: DataTypes.DATE,
productId: {
type: DataTypes.INTEGER,
references: { // 外键
model: Product,
key: 'primaryId'
}
}
}, {
tableName: 'B'
});
// 建立关联
// 一个商品有多个售卖记录
Product.hasMany(Sale, { foreignKey: 'productId' });
// 售卖记录属于一个商品
Sale.belongsTo(Product, { foreignKey: 'productId' });
// 查询商品id为3的商品信息和售卖信息
try {
const productWithSales = await Product.findByPk(3, {
attributes :[ // 如果Product信息全量返回,就不配置
"primaryId",
[ "name","productName"] // 将name重命名为productName
],
include: [{
model: Sale,
attributes:["quantity","saleDate"], // 如果Product信息全量返回,就不配置
required: false // LEFT OUTER JOIN,即使没有售卖记录也返回商品
// required: true // 则只返回有售卖记录的商品(INNER JOIN)
}]
});
console.log(productWithSales.toJSON());
/* 输出示例:
* {
* primaryId: 3,
* name: '手机',
* price: 2999,
* Sales: [
* { id: 1, quantity: 10, saleDate: '2025-01-01', productId: 3 },
* { id: 2, quantity: 5, saleDate: '2025-01-02', productId: 3 }
* ]
* }
*/
} catch (err) {
}
9、可视化数据库工具 Navicat

10、接口调试统计 apifox

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)