这篇文章将为大家详细讲解有关怎么使用Nodejs连接Mysql实现基本的增删改查操作,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。 接下来示例代码的主要技术点包括 基础框架 Koa Koa-router koa-nunjucks-2
Mysql连接包
0、前置需求 安装mysql数据库并启动 安装Nodejs(这个应该都木有问题)
1、node连接数据库 创建一个空的文件夹 执行 yarn add koa koa-router mysql 在根目录下创建一个js(test.js)文件,用来测试连接数据库操作 我们先在test.js中写一段代码,输出hello,保证启动程序不报错 const Koa = require("koa") // 导入koa
const Router = require("koa-router") //导入koa-router
const mysql = require("mysql") // 导入mysql,连接mysql 需要用到
const app = new Koa(); // 实例化koa
const router = new Router(); // 实例化路由
// 创建一个路径为/hello的get请求
router.get("/hello", async ctx => {
// 返回 字符串 hello
ctx.body = "hello"
})
// koa注册路由相关
app
.use(router.routes())
.use(router.allowedMethods())
// 监听端口
.listen(3333,()=>{
console.log("server running port:" + 3333);
}) 在项目根目录下执行 node test.js 或者 nodemon test.js 启动项目 使用 nodemon 启动项目需要全局安装 yarn global add nodemon 或者npm i -g nodemon 使用nodemon 启动项目,nodemon 将监视启动目录中的文件,如果有任何文件更改,nodemon 将自动重新启动node应用程序,强烈建议使用 nodemon 启动node项目 项目启动完成后,我们在浏览器输入 http://localhost:3333/hello ,就可以看到页面中输出 文字 hello 了
 这个界面出现后,就证明我们的项目启动没有问题 接下来我们就用node连接mysql数据库了
我们先准备一波数据 CREATE DATABASE db1;
USE db1;
CREATE TABLE user (
id INT PRIMARY KEY auto_increment,
NAME VARCHAR(20) NOT NULL,
age INT NOT NULL
);
INSERT INTO user VALUES
(null, "张三", 23),
(null, "李四", 24),
(null, "王五", 25),
(null, "赵六", 26);
2、 连接mysql数据库,实现表格显示功能 接下来我们在test.js中写连接mysql的代码 const Koa = require("koa") // 导入koa
const Router = require("koa-router") //导入koa-router
const mysql = require("mysql") // 导入mysql,连接mysql 需要用到
const app = new Koa(); // 实例化koa
const router = new Router(); -- 实例化路由
// mysqljs 连接 mysql数据库
let connection = mysql.createConnection({
host: '127.0.0.1', // mysql所在的主机,本地的话就是 127.0.0.1 或者 localhost, 如果数据库在服务器上,就写服务器的ip
user: 'root', // mysql的用户名
password: '密码', // mysql的密码
database: 'db1' // 你要连接那个数据库
})
// 连接 mysql
connection.connect(err=>{
// err代表失败
if(err) {
console.log("数据库初始化失败");
}else {
console.log("数据库初始化成功");
}
})
// 创建一个路径为/hello的get请求
router.get("/hello", async ctx => {
// 返回 字符串 hello
ctx.body = "hello"
})
// koa注册路由相关
app
.use(router.routes())
.use(router.allowedMethods())
// 监听端口
.listen(3333,()=>{
console.log("server running port:" + 3333);
})


我们在 connection.connect方法下加入这段查询代码 connection.query方法的第一个参数是一个字符串类型的sql 语句,第二个参数是可选的,后边会说,最后是一个包含了错误信息和正确响应结果数据的方法 const selectSql = "SELECT * FROM user"
connection.query(selectSql, (err,res) => {
if(err) console.log(err);
console.log(res);
})
返回的数据是这样的 
通过添加这段代码把数据以JSON的格式返回给浏览器 // 因为 mysqljs不支持 Promise方式CRUD数据
// 所以我们做一个简单的封装
function resDb(sql) {
return new Promise((resolve,reject) => {
connection.query(sql, (err,res) => {
if(err) {
reject(err)
}else {
resolve(res)
}
})
})
}
//请求 /userAll 的时候返回数据
router.get("/userAll", async ctx => {
ctx.body = await resDb("SELECT * FROM user")
}) 
test.js中添加这段代码
const koaNunjucks = require('koa-nunjucks-2');
const path = require('path');
// 注入 nunjucks 模板引擎
app.use(koaNunjucks({
ext: 'html', // html文件的后缀名
path: path.join(__dirname, 'views'), // 视图文件放在哪个文件夹下
nunjucksConfig: {
trimBlocks: true // 自动去除 block/tag 后面的换行符
}
}));
//在 /userAll这个路由中我们不直接返回数据了,我们返回table.html页面
router.get("/userAll", async ctx => {
const userAll = await resDb("SELECT * FROM user")
await ctx.render("table",{userAll})
}) 通过nunjucks模板引擎,我们把所有的html文件统一放在了根目录的views文件夹下,那么我们需要在根目录下创建一个views文件夹,在文件夹中创建 table.html的文件,文件代码如下 <!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.table{
width: 500px;
}
td{
text-align: center;
}
</style>
</head>
<body>
<table border="1" cellspacing="0">
<thead>
<tr>
<th>id</th>
<th>姓名</th>
<th>年龄</th>
</tr>
</thead>
<tbody>
{% for user in userAll %}
<tr >
<td>{{user.id}}</td>
<td>{{user.NAME}}</td>
<td>{{user.age}}</td>
</tr>
{% endfor %}
</tbody>
</table>
</body>
</html> 重启服务器后 访问 http://localhost:3333/userAll 
这个页面出来后,显示部分就大功告成了 查询功能做完了,接下来我们就可以实现新增功能
3、 添加数据到mysql数据库中 
当我们输入完用户名和年龄点击添加按钮后,浏览器会通过 get请求 把数据发送到 /addUser 这个路由中,接下来,我们在test.js中接收一下前端传的参数,并且把参数保存到数据库中。然后刷新页面 //请求 /addUser 接受前端传过来的数据,并且把数据持久化到数据库中
router.get("/addUser", async ctx => {
const { name, age } = ctx.query
// 判断 name 和 age是否有值,都有值时,数据存入数据库,刷新表格页面
// 否则直接返回到表格页面
if(name && age) {
await resDb("INSERT INTO user values(null,?,?)",[name, age])
}
//重定向路由,到 userAll
ctx.redirect("/userAll")
}) 为了提高 resDb 的健壮性,我们对这个方法进行了升级 function resDb(sql, params) {
return new Promise((resolve,reject) => {
let sqlParamsList = [sql]
if(params) {
sqlParamsList.push(params)
}
connection.query(...sqlParamsList, (err,res) => {
if(err) {
reject(err)
}else {
resolve(res)
}
})
})
} 升级之后的这个方法适合 CRUD的 promise 化了,当然 修改和删除功能下边我们会说 到这个时候,我们的新增功能就完成了,那么我们来看一波截图,并且理一下逻辑


4、 通过id更新数据 更新数据的前端部分,我们就不写模态框了,直接写个类似新增的表单,实现更新的操作吧,其实新增和更新功能非常类似,有差别的地方只是sql的写法 我们先把table.html页面改造一下 <form action="/updateUser">
<label for="id">
id:
<input type="number" name="id" placeholder="请输入要更新的ID">
</label>
<label for="name">
用户名:
<input type="text" name="name" placeholder="请输入用户名">
</label>
<label for="age">
年龄:
<input type="number" name="age" min="0" placeholder="请输入年龄">
</label>
<input type="submit" value="修改">
</form> 下面我们看下后台的代码 //请求 /updateUser 接受前端传过来的数据,并且把数据持久化到数据库中
router.get("/updateUser", async ctx => {
const { id, name, age } = ctx.query
// 判断 id, name 和 age是否有值,都有值时,更新数据库中的数据,刷新表格页面
// 否则直接返回到表格页面
if(id, name && age) {
await resDb("UPDATE user SET name=?, age=? WHERE id=?",[name, age, id])
}
//重定向路由,到 userAll
ctx.redirect("/userAll")
}) 代码逻辑和新增部分的逻辑是一样的, 刚才在写新增和更新的sql代码,大家会看到sql语句中有? 占位符,第二个参数数组是? 占位符对应的内容。那么这个时候大家肯定会有这样一个疑问,为啥我们不直接把前端传过来的参数拼进去。非得这么麻烦。 其实这样通过占位符的方式写sql 是为了防止 sql注入 ,有关sql注入 的文章大家可以参考这篇 sql注入原理及防范
5、通过id删除单条数据 老规矩我们先把table.html页面改造一下 <table class="table" border="1" cellspacing="0">
<thead>
<tr>
<th>id</th>
<th>姓名</th>
<th>年龄</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{% for user in userAll %}
<tr >
<td>{{user.id}}</td>
<td>{{user.NAME}}</td>
<td>{{user.age}}</td>
<td>
<a href={{'/delete/'+user.id}}>删除</a>
</td>
</tr>
{% endfor %}
</tbody>
</table> 看下页面效果 
老规矩,下面我们来看看后台的代码 //请求/delete/:id 接受前端传过来的数据,并且把对应的id的数据删掉
router.get("/delete/:id", async ctx => {
const { id } = ctx.params
// 判断 id否有值,有值时,根据id删除数据库中的数据,刷新表格页面
// 否则直接返回到表格页面
if(id) {
await resDb("DELETE FROM user WHERE id=?",[id])
}
//重定向路由,到 userAll
ctx.redirect("/userAll")
}) 到目前为止对表格的增删改查(CRUD),就都已经写完了。
6、 完整代码 const Koa = require("koa")
const Router = require("koa-router")
const mysql = require("mysql")
const koaNunjucks = require('koa-nunjucks-2');
const path = require('path');
const app = new Koa();
const router = new Router();
// mysqljs 连接 mysql数据库
let connection = mysql.createConnection({
host: '127.0.0.1', // mysql所在的主机,本地的话就是 127.0.0.1 或者 localhost, 如果数据库在服务器上,就写服务器的ip
user: 'root', // mysql的用户名 默认root
password: 'mysql密码', // mysql的密码
database: 'db1' // 你要连接那个数据库
})
// 连接 mysql
connection.connect(err=>{
// err代表失败
if(err) {
console.log("数据库初始化失败");
}else {
console.log("数据库初始化成功");
}
})
// 因为 mysqljs不支持 Promise方式CRUD数据
// 所以我们做一个简单的封装
function resDb(sql, params) {
return new Promise((resolve,reject) => {
let sqlParamsList = [sql]
if(params) {
sqlParamsList.push(params)
}
connection.query(...sqlParamsList, (err,res) => {
if(err) {
reject(err)
}else {
resolve(res)
}
})
})
}
// 注入 nunjucks 模板引擎
app.use(koaNunjucks({
ext: 'html', // html文件的后缀名
path: path.join(__dirname, 'views'), // 视图文件放在哪个文件夹下
nunjucksConfig: {
trimBlocks: true // 自动去除 block/tag 后面的换行符
}
}));
//请求 /userAll 的时候返回数据
router.get("/userAll", async ctx => {
const userAll = await resDb("SELECT * FROM user")
await ctx.render("table",{userAll})
})
//请求 /addUser 接受前端传过来的数据,并且把数据持久化到数据库中
router.get("/addUser", async ctx => {
const { name, age } = ctx.query
// 判断 name 和 age是否有值,都有值时,数据存入数据库,刷新表格页面
// 否则直接返回到表格页面
if(name && age) {
await resDb("INSERT INTO user values(null,?,?)",[name, age])
}
//重定向路由,到 userAll
ctx.redirect("/userAll")
})
//请求 /updateUser 接受前端传过来的数据,并且把数据持久化到数据库中
router.get("/updateUser", async ctx => {
const { id, name, age } = ctx.query
// 判断 id, name 和 age是否有值,都有值时,更新数据库中的数据,刷新表格页面
// 否则直接返回到表格页面
if(id, name && age) {
await resDb("UPDATE user SET name=?, age=? WHERE id=?",[name, age, id])
}
//重定向路由,到 userAll
ctx.redirect("/userAll")
})
//请求/delete/:id 接受前端传过来的数据,并且把对应的id的数据删掉
router.get("/delete/:id", async ctx => {
const { id } = ctx.params
// 判断 id否有值,有值时,根据id删除数据库中的数据,刷新表格页面
// 否则直接返回到表格页面
if(id) {
await resDb("DELETE FROM user WHERE id=?",[id])
}
//重定向路由,到 userAll
ctx.redirect("/userAll")
})
//测试代码
router.get("/hello", ctx => {
ctx.body = "hello"
})
app
.use(router.routes())
.use(router.allowedMethods())
.listen(3333,()=>{
console.log("server running port:" + 3333);
}) views/table.html <!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.table {
width: 500px;
}
td {
text-align: center;
}
</style>
</head>
<body>
<form action="/addUser" autocomplete="off">
<label for="name">
用户名:
<input type="text" name="name" placeholder="请输入用户名">
</label>
<label for="age">
年龄:
<input type="number" name="age" min="0" placeholder="请输入年龄">
</label>
<input type="submit" value="添加">
</form>
<form action="/updateUser" autocomplete="off">
<label for="id">
id:
<input type="number" name="id" placeholder="请输入要更新的ID">
</label>
<label for="name">
用户名:
<input type="text" name="name" placeholder="请输入用户名">
</label>
<label for="age">
年龄:
<input type="number" name="age" min="0" placeholder="请输入年龄">
</label>
<input type="submit" value="修改">
</form>
<table border="1" cellspacing="0">
<thead>
<tr>
<th>id</th>
<th>姓名</th>
<th>年龄</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{% for user in userAll %}
<tr>
<td>{{user.id}}</td>
<td>{{user.NAME}}</td>
<td>{{user.age}}</td>
<td>
<a href={{'/delete/'+user.id}}>删除</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</body>
</html>
7、写在最后 关于“怎么使用Nodejs连接Mysql实现基本的增删改查操作”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。
|