이 글에서는 Nodejs를 사용하여 Mysql에 연결하고 기본 CRUD 작업을 구현하는 방법을 소개합니다. 도움이 필요한 친구들이 모두 참고할 수 있기를 바랍니다.
【추천 학습: "nodejs tutorial"】
다음 샘플 코드의 주요 기술 포인트는 다음과 같습니다
기본 프레임워크
Koa
Koa 라우터
koa-nunjucks-2
Mysql 연결 패키지
mysqljs
0, 사전 요구 사항
mysql 데이터베이스를 설치하고 시작하세요
Nodejs를 설치하세요(문제 없을 겁니다)
1. 노드를 데이터베이스에 연결하세요
빈 폴더 만들기
실행 yarn add koa koa-router mysql code><code>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); })
当终端输出数据库初始化成功
文字就代表,数据库连接成功了
刚才我们已经在db1数据库中准备了四条数据,接下来我们就可以把数据查询出来,展示在控制台了
我们在 connection.connect方法下加入这段查询代码
connection.query方法的第一个参数是一个字符串类型的sql
语句,第二个参数是可选的,后边会说,最后是一个包含了错误信息和正确响应结果数据的方法
const selectSql = "SELECT * FROM user" connection.query(selectSql, (err,res) => { if(err) console.log(err); console.log(res); })
返回的数据是这样的
这个时候数据库中的数据就已经被查询出来了,那么我们就可以把这些数据通过JSON的格式返回给前端了
通过添加这段代码把数据以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") })
这个数据才是我们所需要的,呃呃呃,数据是返回了,我们可是做前端的,怎么能没有页面呐,先加入一个展示数据的表格页面,这里使用的是 nunjucks
模板引擎,先来安装一下yarn add koa-nunjucks-2
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
데이터베이스 연결 작업을 테스트하기 위해 루트 디렉터리에 js(test.js) 파일을 생성합니다
<form action="/addUser"> <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>
node test.js
또는 nodemon test.js
를 실행하여 프로젝트를 시작하세요🎜🎜🎜🎜 < code>nodemon 프로젝트를 시작하려면 yarn global add nodemon
을 전역적으로 설치하거나 npm i -g nodemon
🎜🎜🎜🎜nodemon<을 사용하세요. /code>를 사용하여 프로젝트를 시작하면 <code>nodemon
시작 디렉터리의 파일이 모니터링됩니다. 파일이 변경되면 nodemon
이 자동으로 노드 애플리케이션을 다시 시작하는 것이 좋습니다. nodemon
을 사용하여 노드 프로젝트 🎜🎜🎜🎜 프로젝트를 시작하려면 시작이 완료된 후 브라우저에 http://localhost:3333/hello
를 입력하면 됩니다. 페이지에서 hello 출력 텍스트를 볼 수 있습니다🎜//请求 /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") })
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) } }) }) }
🎜
🎜🎜🎜🎜🎜🎜터미널에서 데이터베이스 초기화 성공
이 출력되면 텍스트는 데이터베이스 연결이 성공했음을 의미합니다🎜🎜🎜🎜지금 준비했습니다 다음으로 데이터를 쿼리하여 콘솔에 표시할 수 있습니다🎜🎜🎜🎜🎜🎜연결 메서드 아래에 이 쿼리 코드를 추가합니다.🎜🎜🎜🎜연결의 첫 번째 매개변수입니다. .query 메소드는 문자열 형식의 sql
문이고 두 번째 매개변수는 선택사항이며 나중에 설명하겠습니다. 마지막으로 오류 정보와 올바른 응답 결과 데이터를 포함하는 메소드가 있습니다🎜
<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") })
nunjucks
템플릿 엔진을 사용합니다. 먼저 yarn add koa-nunjucks-2</ code>🎜🎜🎜🎜🎜🎜test.js를 설치하세요. 🎜🎜<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:js;toolbar:false;"> <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={{&#39;/delete/&#39;+user.id}}>删除</a>
</td>
</tr>
{% endfor %}
</tbody>
</table></pre><div class="contentsignin">로그인 후 복사</div></div><div class="contentsignin">로그인 후 복사</div></div>🎜🎜🎜nunjucks 템플릿 엔진을 통해 모든 html 파일을 루트 디렉터리의 views 폴더에 넣은 다음 루트 디렉터리에 views 폴더를 만들고 해당 폴더에 table.html 파일을 만들어야 합니다. 파일 코드는 다음과 같습니다🎜<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:js;toolbar:false;"> //请求/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")
})</pre><div class="contentsignin">로그인 후 복사</div></div><div class="contentsignin">로그인 후 복사</div></div>🎜🎜🎜서버를 다시 시작한 후 <code>http://localhost:3333/userAll
에 접속하세요🎜🎜 🎜🎜🎜🎜이 페이지가 나오면 표시 부분이 완료됩니다🎜 🎜🎜🎜쿼리 기능이 완성되면 새로운 기능을 구현할 수 있습니다🎜3、 添加数据到mysql数据库中
我们先把table.html页面的添加部分写完
<form action="/addUser"> <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>
这个时候页面是长这样的
当我们输入完用户名和年龄点击添加按钮后,浏览器会通过 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、 完整代码
目录结构
package.json
{ "koa": "^2.13.1", "koa-nunjucks-2": "^3.0.2", "koa-router": "^10.0.0", "mysql": "^2.18.1" }
test.js
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数据库,并且实现基于模板引擎的增删改查
功能,以及对数据库返回结果简单的做了一个promise封装,也对koa及其实例中用到的插件做了相关的介绍
更多编程相关知识,请访问:编程视频!!
위 내용은 Nodejs를 사용하여 Mysql에 연결하고 기본 추가, 삭제, 수정 및 쿼리 작업을 구현하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!