# nodejs学习-2025-12 **Repository Path**: 1160/node.js-learning--2022-12 ## Basic Information - **Project Name**: nodejs学习-2025-12 - **Description**: 课程链接: https://www.bilibili.com/video/BV1d67GzsEoX?spm_id_from=333.788.player.switch&vd_source=59fab4ae7f7b6462cea577f55587fe78 关注官网: https://clwy.cn/ - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-12-20 - **Last Updated**: 2025-12-21 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README - 课程链接: https://www.bilibili.com/video/BV1d67GzsEoX?spm_id_from=333.788.player.switch&vd_source=59fab4ae7f7b6462cea577f55587fe78 - 关注官网:https://clwy.cn/ ## express-generator ```shell npm install -g express-generator express --no-view 项目名 ``` ## sequelize - 安装全局的 sequelize-cli ```shell npm install -g sequelize-cli ``` - 当前项目也要安装 sequelize 和 mysql2 ```shell npm install sequelize mysql2 --save ``` - 然后运行 sequelize init 完成初始化 - 这时候会创建 - **config/config.js** 数据库连接配置 - migrations 迁移文件 - models 模型文件 - seeders 填充文件/种子文件 ## 配置 数据库连接 - config/config.js 中写入 ```json "development": { "username": "root", "password": 123456, "database": "clwy_api_development", "host": "127.0.0.1", "dialect": "mysql", "timezone": "+08:00" }, ``` - 注意这里配置 database,timezone(这是北京时区+8 区) ## 创建模型 - 在命令行中写入: ```shell sequelize model:generate --name Articles --attributes title:string,content:text ``` - 然后生成模型文件 models/article.js 和 迁移文件 migrations/xxxxxxxxxxxx-create-article.js - **注意:** 命令中一定是 **复数形式的(Articles)**,但是创建出来的模型文件是单数形式的(article.js) - migrations 中,全都是创建表格的操作 - 修改 migrations/xxxxxxxxxxxx-create-article.js 文件,修改 title 为 “不允许 NULL” ```json title: { allowNull: false, type: Sequelize.STRING, }, ``` - 键入命令 ```shell sequelize db:migrate ``` 这时候数据库中就能看到我们创建的 Articles 表了 ## 导入测试数据 - 输入命令: ```shell sequelize seed:generate --name article ``` - 生成填充文件 seeders/xxxxxxxxxxxx-article.js - 这里的 up 是用来填充数据 - down 是用来删除数据 - 写入以下脚本语句 ```javascript await queryInterface.bulkInsert( 'Articles', [ { title: '今天天气真好', content: '天气预报说虽然今天是晴天,可是明天会下雨。', createdAt: new Date(), updatedAt: new Date(), }, { title: '武汉什么早餐最好吃?', content: '毫无疑问是三鲜豆皮 + 热干面 + 米酒', createdAt: new Date(), updatedAt: new Date(), }, ], {} ); ``` - 键入命令 ```shell sequelize db:seed: --seed 20251220093457-article ``` - 这里注意需要找到准确的种子文件名,例如:seeders/20251220093457-article - **当然使用:sequelize db:seed:all** 也行 ## 创建第一个路由 - 详见 **/routes/admin/articles.js** - 同时需要在 **app.js** 中引入 ## 创建第二个路由,根据 ID 查询文章 - 详见 **/routes/admin/articles.js** - 如果查询的 ID 不存在,那么返回 404 错误。 ## 使用 APIFOX 测试接口 - 首先保存成功用力,然后在 **分享文档** 中将文档分享出去。 - 注意:edge 浏览器中必须安装插件,不然会爆出跨域的问题。 ```js // 这个状态码是 201 ,表示创建成功 res.status(status.CREATED).json({ status: true, message: '创建文章成功', data: { ...article.dataValues }, }); ``` - 前端如果使用 application/json,那么不会被 URL 编码。 - 使用 application/x-www-form-urlencoded 会被编码。 - 如果是登录页面传输有密码的数据,那么前端最好使用 哈希 对密码进行加密,然后再传输给后端。 - 后端得到数据之后,再解密。 ## 更新文章 - 这里的更新文章,id 是通过 params 传递的,body 是通过 req.body 传递的,使用的是 application/x-www-form-urlencoded ## 模糊查询 - 这里开始总结前端请求的方式: - 1、直接在 url 中写入 id:/articles/1,这种方式在后端使用 req.params.id 获取 - 2、在 url 中写入参数:/articles?id=1,这种方式在后端使用 req.query.id 获取 - 3、在 body 中写入参数:/articles,这种方式在后端使用 req.body.id 获取 ```js // admin/articles.js // 这里开始模糊查询 if (req.query.title) { // 这里的前后都要加上 %,这样的话表示前后都有内容,才能够模糊匹配 condition.where = { title: { [Op.like]: `%${req.query.title}%` } }; } ``` ## 数据分页 ```SQL SELECT * FROM articles LIMIT 0, 10; ``` - 这里的 0 表示从第几条开始,10 表示取多少条数据。 - offset 表示从第几条开始,limit 表示取多少条数据。 |当前页(currentPage)|从哪里开始(offset)|每页显示多少条(pageSize)| |:---:|:---:|:---:| |第一页|0|10| |第二页|10|10| |第三页|20|10| - offset = (currentPage - 1) \* pageSize; ```js router.get('/', async (req, res) => { try { const condition = { order: [['id', 'DESC']], }; // 这里开始模糊查询 if (req.query.title) { // 这里的前后都要加上 %,这样的话表示前后都有内容,才能够模糊匹配 condition.where = { title: { [Op.like]: `%${req.query.title}%` } }; } // 开始分页 // 当前是第几页,如果不传,那么就是第一页 const currentPage = Math.abs(Number(req.query.currentPage)) || 1; // 每页显示多少条,如果不传,那么就是10条 const pageSize = Math.abs(Number(req.query.pageSize)) || 10; // 从哪里开始查 const offset = (currentPage - 1) * pageSize; condition.limit = pageSize; condition.offset = offset; // 这是原来的,没有分页 // const articles = await Article.findAll(condition); // 这是分页的写法,count是一个表格中,满足模糊查询的条件的数据数量,rows是数据 const { count, rows } = await Article.findAndCountAll(condition); // 这里是默认返回成功,状态码是 200 ,就不用在设置status了。 res.json({ status: true, message: '查询文章列表成功', data: { rows, currentPage, pageSize, total: count }, }); } catch (error) { res.status(status.INTERNAL_SERVER_ERROR).json({ status: false, message: '查询文章列表失败', errors: [error.message], }); } }); ```