【koa】05-koa+mysql实现数据库集成:连接和增删改查
前言
前面我们已经介绍了第二阶段的第1-4点内容,本篇介绍第5点内容:数据库集成(koa+mysql)
也是第二阶段内容的完结。
一、学习目标
在koa项目中正常连接数据库,对数据表进行增删改查的操作。
二、操作步骤
本篇文章会使用到:koa+sequelize+mysql+apipost(用于测试http方法)
注意:文章很多的操作步骤和“express框架的数据库集成”基本上是一样的,参考文章:
【express-generator】09-连接和使用数据库-CRUD 操作(第二阶段完结)-CSDN博客
所以文章中会简单跳过/省略一些简单的步骤。
1、安排依赖
在项目根目录下运行以下命令安装必要的依赖:
npm install koa mysql2 sequelize koa-router koa-bodyparser
2、配置数据库连接
注意:每个人的数据库连接连接信息不一样,对应修改自己的信息。

在state2/models/dbConnect.js中配置数据库连接信息:
// 该文件负责连接数据库
const { Sequelize } = require("sequelize");// 创建数据库连接
const sequelize = new Sequelize("mysite2", "root", "123456aa", {host: "localhost",dialect: 'mysql',logging: false
});const startDB=async()=> {try {await sequelize.authenticate();console.log('数据库已建立起连接.');} catch (error) {console.error('Unable to connect to the database:', error);}
}
startDB()// 向外暴露这个连接实例
module.exports = sequelize;
3、定义数据模型
在state2/models/userModel写入以下代码:
const { DataTypes } = require("sequelize");
const sequelize = require("./dbConnect");// 定义数据模型
module.exports = sequelize.define("koauser", {// 这张表拥有哪些字段name : {type : DataTypes.STRING,allowNull : true},age : {type : DataTypes.INTEGER,allowNull : true},
},{//与模型定义时的名称一致。 // 比如定义了上述定义了content模型,设置了这个字段,创建表的名字也是content。freezeTableName : true, //用于记录数据的创建时间和更新时间。createdAt : false, updatedAt : false
});
这里我们定义了一个名为“koauser”的数据表,有name和age字段,分别是string和integer数据类型。
4、初始化Sequelize和加载模型
在state2/demodels/db.js写入以下代码:
// 该文件负责对数据库进行一个初始化操作
const sequelize = require("./dbConnect"); // 数据库连接实例const userModel = require("./userModel"); // 数据模型
const initData=async function () {// 将数据模型和表进行同步await sequelize.sync({alter: true,})// 同步完成之后,有一些表是需要一些初始化数据// 查询这张表有没有内容,没有内容才初始化数据const userCount = await userModel.count();if (!userCount) {// 进入此 if,说明该表没有数据,我们进行一个初始化await userModel.create({name: "Tom",age:18})console.log("初始化内容数据表数据完毕...");}console.log("数据库数据已经准备完毕....");
}
initData()
5、创建Koa应用并集成Sequelize
在state2/demo5.js中写入以下代码:
const Koa = require('koa');
const Router = require('koa-router');
const bodyParser = require('koa-bodyparser');
// const models = require('./models');
const userModel = require('./models/userModel');
const app = new Koa();
const router = new Router();require('./models/db');
// 使用bodyParser中间件解析请求体
app.use(bodyParser());// 定义路由
router.get('/', async (ctx) => {ctx.body = 'Welcome to Koa with Sequelize!';
});// 使用路由中间件
app.use(router.routes()).use(router.allowedMethods());app.listen(3000, () => {console.log('Server is running at http://localhost:3000');
});
启动服务,看是否正常连接数据库和创建、初始化数据表。
在state2的目录下打开终端,执行node demo5.js

启动之前,数据库的表情况

启动之后,多了一个koauser的数据表,并且有一条数据。

6、增删改查(CRUD)操作
Create:增加
Read:查
Update:更新
Delete:删除
6.1、查找所有用户信息
在state2/demo5.js中新增代码:
// 查找所有用户
router.get('/users', async (ctx) => {const users = await userModel.findAll();ctx.body = users;
});
方法放在这个位置

测试:启动服务+apipost工具
新增get方法,点击发送则会得到以下结果

6.2、 增加新的用户
// 创建用户
router.post('/user', async (ctx) => {const { name, age } = ctx.request.body;try {const user = await userModel.create({ name,age });ctx.body = user;} catch (error) {ctx.status = 400;ctx.body = { error: error.message };}
});
测试:启动服务+添加post方法

在数据表中刷新可以看到新增的数据项
6.3、查找单条用户数据
为了后续测试,先增加了几条数据

// 查找单个用户
router.get('/user/:id', async (ctx) => {const { id } = ctx.params;try {const user = await userModel.findByPk(id);if (user) {ctx.body = user;} else {ctx.status = 404;ctx.body = { error: 'User not found' };}} catch (error) {ctx.status = 400;ctx.body = { error: error.message };}
});
测试:启动服务+添加get方法
查找id为1的数据项

查找id为3的数据项
6.4、更新用户信息
// 更新用户router.put('/user/:id', async (ctx) => {const { id } = ctx.params;const { name,age } = ctx.request.body;try {const user = await userModel.findByPk(id);if (user) {await user.update({ name,age });ctx.body = user;} else {ctx.status = 404;ctx.body = { error: 'User not found' };}} catch (error) {ctx.status = 400;ctx.body = { error: error.message };}});
测试:启动服务+测试put方法
我们尝试将id为1的数据项,对name进行修改成"Rura"(原本是Tom)

响应结果

刷新数据表,可以看见id为1的数据项的name已经被修改。
6.5、删除用户信息
// 删除用户router.delete('/user/:id', async (ctx) => {const { id } = ctx.params;try {const user = await userModel.findByPk(id);if (user) {await user.destroy();ctx.status = 204;} else {ctx.status = 404;ctx.body = { error: 'User not found' };}} catch (error) {ctx.status = 500;ctx.body = { error: error.message };}});
测试:启动服务+测试delete方法
这里我们尝试将id为4的数据项进行删除

点击发送,在数据表中刷新查看结果。

三、小结
这篇我们介绍了在koa中如何使用数据库,创建和初始化数据表,并介绍了数据表的常用操作:增删改查,文章以“代码示范+测试”的内容呈现。文章中用到的代码示范,我已经同步更新在代码仓库中,有需要的朋友请自行获取:koa练习: koa练习
欢迎大家star和fork,也欢迎一起完善这个代码仓~
koa专栏的第二阶段的内容到此结束,后续的文章我会更新第三阶段的内容。
关注我,及时获取最新文章消息~
相关文章:
【koa】05-koa+mysql实现数据库集成:连接和增删改查
前言 前面我们已经介绍了第二阶段的第1-4点内容,本篇介绍第5点内容:数据库集成(koamysql) 也是第二阶段内容的完结。 一、学习目标 在koa项目中正常连接数据库,对数据表进行增删改查的操作。 二、操作步骤 本篇文章…...
【数据结构】队列(Queue)
Queue 定义 Java中的队列(Queue)是一种先进先出(FIFO)的数据结构。队列只允许在一段进行插入数据操作,称为入队,在另一端进行删除数据操作,称为出队。我们可以把队列形象看作为排队。在最前面的进行出队,从最后面进行入队。 队列…...
机器学习PCA和LDA
主成分分析(PCA, Principal Component Analysis)和线性判别分析(LDA, Linear Discriminant Analysis)是两种常用的降维方法,它们虽然都用于数据降维,但核心思想和应用场景不同。 PCA(主成分分析…...
RocketMQ - 常见问题
RocketMQ常见问题 文章目录 RocketMQ常见问题一:消息幂等问题1:什么是消费幂等2:消息重复的场景分析2.1:发送时消息重复2.2:消费时消息重复2.3:Rebalance时消息重复 3:通用解决方案3.1ÿ…...
kafka消费能力压测:使用官方工具
背景 在之前的业务场景中,我们发现Kafka的实际消费能力远低于预期。尽管我们使用了kafka-go组件并进行了相关测试,测试情况见《kafka-go:性能测试》这篇文章。但并未能准确找出消费能力低下的原因。 我们曾怀疑这可能是由我的电脑网络带宽问题或Kafka部…...
基于Spring Boot的社区居民健康管理平台的设计与实现
目录 1 绪论 1.1 研究现状 1.2 研究意义 1.3 组织结构 2 技术介绍 2.1 平台开发工具和环境 2.2 Vue介绍 2.3 Spring Boot 2.4 MyBatis 2.5 环境搭建 3 系统需求分析 3.1 可行性分析 3.2 功能需求分析 3.3 系统用例图 3.4 系统功能图 4 系统设计 4.1 系统总体描…...
网络安全架构战略 网络安全体系结构
本节书摘来自异步社区《网络安全体系结构》一书中的第1章,第1.4节,作者【美】Sean Convery 1.4 一切皆为目标 网络安全体系结构 当前的大型网络存在着惊人的相互依赖性,作为一名网络安全设计师,对这一点必须心知肚明。Internet就…...
【Spring+MyBatis】_图书管理系统(中篇)
【SpringMyBatis】_图书管理系统(上篇)-CSDN博客文章浏览阅读654次,点赞4次,收藏7次。(1)当前页的内容records(类型为List);参数:userNameadmin&&pas…...
Python - 爬虫利器 - BeautifulSoup4常用 API
文章目录 前言BeautifulSoup4 简介主要特点:安装方式: 常用 API1. 创建 BeautifulSoup 对象2. 查找标签find(): 返回匹配的第一个元素find_all(): 返回所有匹配的元素列表select_one() & select(): CSS 选择器 3. 访问标签内容text 属性: 获取标签内纯文本get_t…...
宝塔面板开始ssl后,使用域名访问不了后台管理
宝塔面板后台开启ssl访问后,用的证书是其他第三方颁发的证书 再使用 域名/xxx 的形式:https://域名:xxx/xxx 访问后台,结果出现如下,不管使用 http 还是 https 的路径访问都进不后台管理 这个时候可以使用 https://ip/xxx 的方式来…...
大一计算机的自学总结:前缀树(字典树、Trie树)
前言 前缀树,又称字典树,Trie树,是一种方便查找前缀信息的数据结构。 一、字典树的实现 1.类描述实现 #include <bits/stdc.h> using namespace std;class TrieNode { public:int pass0;int end0;TrieNode* nexts[26]{NULL}; };Tri…...
docker 安装的open-webui链接ollama出现网络错误
# 故事背景 部署完ollama以后,使用谷歌浏览器的插件Page Assist - 本地 AI 模型的 Web UI 可以比较流畅的使用DeepSeek,但是只局限于个人使用,想分享给更多的小伙伴使用,于是打算使用open-webui 来管理用户,经官网推荐…...
未来游戏:当人工智能重构虚拟世界的底层逻辑
未来游戏:当人工智能重构虚拟世界的底层逻辑 在《赛博朋克2077》夜之城的霓虹灯下,玩家或许已经注意到酒吧里NPC开始出现微表情变化;在《艾尔登法环》的开放世界中,敌人的战术包抄逐渐显露出类人智慧。这些细节预示着游戏产业正站…...
Redis集群主从切换源码解读
一切的开始 打开Redis5.0.5的源码中server.c,找到如下代码,这里运行了一个定时任务,每隔100毫秒执行一次。 /* Run the Redis Cluster cron. *//** 每隔100毫秒执行一次* 要求开启集群模式*/run_with_period(100) {if (server.cluster_enabl…...
javacv将mp4视频切分为m3u8视频并播放
学习链接 ffmpeg-demo 当前对应的 gitee代码 Spring boot视频播放(解决MP4大文件无法播放),整合ffmpeg,用m3u8切片播放。 springboot 通过javaCV 实现mp4转m3u8 上传oss 如何保护会员或付费视频?优酷是怎么做的? - HLS 流媒体加密 ffmpe…...
Golang学习笔记_33——桥接模式
Golang学习笔记_30——建造者模式 Golang学习笔记_31——原型模式 Golang学习笔记_32——适配器模式 文章目录 桥接模式详解一、桥接模式核心概念1. 定义2. 解决的问题3. 核心角色4. 类图 二、桥接模式的特点三、适用场景1. 多维度变化2. 跨平台开发3. 动态切换实现 四、与其他…...
蜂鸟视图发布AI智能导购产品:用生成式AI重构空间服务新范式
在人工智能技术飞速发展的今天,北京蜂鸟视图正式宣布推出基于深度求索(DeepSeek)等大模型的《AI智能导购产品》,通过生成式AI与室内三维地图的深度融合,重新定义空间场景的智能服务体验。 这一创新产品将率先应用于购物…...
AI服务器散热黑科技:让芯片“冷静”提速
AI 服务器为何需要散热黑科技 在人工智能飞速发展的当下,AI 服务器作为核心支撑,作用重大。从互联网智能推荐,到医疗疾病诊断辅助,从金融风险预测,到教育个性化学习,AI 服务器广泛应用,为各类复…...
数据结构-栈、队列、哈希表
1栈 1.栈的概念 1.1栈:在表尾插入和删除操作受限的线性表 1.2栈逻辑结构: 线性结构(一对一) 1.3栈的存储结构:顺序存储(顺序栈)、链表存储(链栈) 1.4栈的特点: 先进后出(fisrt in last out FILO表),后进先出 //创建栈 Stacklist create_stack() {Stacklist lis…...
安装海康威视相机SDK后,catkin_make其他项目时,出现“libusb_set_option”错误的解决方法
硬件:雷神MIX G139H047LD 工控机 系统:ubuntu20.04 之前运行某项目时,处于正常状态。后来由于要使用海康威视工业相机(型号:MV-CA013-21UC),便下载了并安装了该相机的SDK,之后运行…...
树莓派超全系列教程文档--(61)树莓派摄像头高级使用方法
树莓派摄像头高级使用方法 配置通过调谐文件来调整相机行为 使用多个摄像头安装 libcam 和 rpicam-apps依赖关系开发包 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 配置 大多数用例自动工作,无需更改相机配置。但是,一…...
python/java环境配置
环境变量放一起 python: 1.首先下载Python Python下载地址:Download Python | Python.org downloads ---windows -- 64 2.安装Python 下面两个,然后自定义,全选 可以把前4个选上 3.环境配置 1)搜高级系统设置 2…...
Swift 协议扩展精进之路:解决 CoreData 托管实体子类的类型不匹配问题(下)
概述 在 Swift 开发语言中,各位秃头小码农们可以充分利用语法本身所带来的便利去劈荆斩棘。我们还可以恣意利用泛型、协议关联类型和协议扩展来进一步简化和优化我们复杂的代码需求。 不过,在涉及到多个子类派生于基类进行多态模拟的场景下,…...
Golang dig框架与GraphQL的完美结合
将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用,可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器,能够帮助开发者更好地管理复杂的依赖关系,而 GraphQL 则是一种用于 API 的查询语言,能够提…...
屋顶变身“发电站” ,中天合创屋面分布式光伏发电项目顺利并网!
5月28日,中天合创屋面分布式光伏发电项目顺利并网发电,该项目位于内蒙古自治区鄂尔多斯市乌审旗,项目利用中天合创聚乙烯、聚丙烯仓库屋面作为场地建设光伏电站,总装机容量为9.96MWp。 项目投运后,每年可节约标煤3670…...
基于Docker Compose部署Java微服务项目
一. 创建根项目 根项目(父项目)主要用于依赖管理 一些需要注意的点: 打包方式需要为 pom<modules>里需要注册子模块不要引入maven的打包插件,否则打包时会出问题 <?xml version"1.0" encoding"UTF-8…...
实现弹窗随键盘上移居中
实现弹窗随键盘上移的核心思路 在Android中,可以通过监听键盘的显示和隐藏事件,动态调整弹窗的位置。关键点在于获取键盘高度,并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...
CMake控制VS2022项目文件分组
我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...
学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2
每日一言 今天的每一份坚持,都是在为未来积攒底气。 案例:OLED显示一个A 这边观察到一个点,怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 : 如果代码里信号切换太快(比如 SDA 刚变,SCL 立刻变&#…...
C++:多态机制详解
目录 一. 多态的概念 1.静态多态(编译时多态) 二.动态多态的定义及实现 1.多态的构成条件 2.虚函数 3.虚函数的重写/覆盖 4.虚函数重写的一些其他问题 1).协变 2).析构函数的重写 5.override 和 final关键字 1&#…...
