学习目标:
mysql模块
学生选课系统综合演练

目录

1 mysql模块

1.1 安装

1.2 应用

1.3 连接池

2 综合演练

 2.2 初始化工程

2.3 Message封装

2.4 接口编写

2.5 前端开发

1 mysql模块

mysql模块提供了nodejs操作mysql数据库的api, https://www.npmjs.com/package/
mysql

1.1 安装

$ cnpm install mysql --save

1.2 应用

每次进行sql操作的时候都创建一个连接对象,使用完成后将连接对象关闭,关闭后
的连接对象无法再次使用。这不利于我们进行代码封装。

var mysql = require('mysql');
var connection = mysql.createConnection({
host : '121.199.29.84',
user : 'briup',
password : 'briup',
database : 'briup-sc'
});
connection.connect();
connection.query('SELECT * FROM tbl_student', function (error,
results, field){
if (error) throw error;
console.log('The solution is: ', results);
});
connection.end();

1.3 连接池

连接池技术可以创建多个连接放到连接池中,我们可以将连接池的代码进行封装,
每次需要连接的的时候,通过连接池获取一个连接对象即可,使用完成后将该连接
对象释放。

var mysql = require('mysql');
var pool = mysql.createPool({
connectionLimit: 10,
host: '121.199.29.84',
user: 'briup',
password: 'briup',
database: 'briup-sc'
});
// 获取连接
pool.getConnection((err, connection) => {
if (err) throw err;
// 查询
connection.query(sql, function (error, results, fields) {
if (error) throw error;
// 释放
connection.release(); resp.send(Message.success(results));
});
})

2 综合演练

截止目前,我们已经完成了nodejs基础语法、核心模块、http服务器编程、数据库
编程的学习,接下来通过这些技术完成后端服务的开发。
2.1 数据建模
在学生选课业务中,一个学生可以选多⻔课程,一⻔课程可以被多个人来选,一个
课程只能由一个教师来负责。

nodejs mysql数据库 自增id node mysql model_sql

 2.2 初始化工程

$ mkdir sc-server
$ cd sc-server
$ npx express-generator
$ cnpm install
$ cnpm install mysql --save
$ cnpm install cors --save
$ npm start

经过上述操作,我们会创建一个基于express的sc-server的工程,该工程中默认包含
了 cookie-parser、debug、express、jade、morgan、body-parser(内置)、serve-
static依赖, 我们还需要手动安装cors和mysql,npm start命令会启动该工程,默认
占据3000端口,需要注意的是,如果后台接口代码更新,请务必重启该工程。

2.3 Message封装

我们期望,后端提供的所有端口都具有统一的规范,例如:

nodejs mysql数据库 自增id node mysql model_node.js_02

 这样,方便前端统一处理。如下是封装代码。

class Message {
constructor(status, message, data) {
this.status = status;
this.message = message;
this.data = data;
this.timestamp = new Date().getTime();
}
static success(param) {
if (typeof param == 'string') {
return new Message(200, param, null)
} else if (typeof param == 'object') {
return new Message(200, 'success', param)
}
}
static error(message) {
return new Message(500, message, null);
}
}
module.exports = Message;

2.4 接口编写

接口开发的时候注意要分模块开发,即每个模块创建一个新的router,每个接口沿
着 获取 参数-> 业务逻辑处理 -> 数据库操作 -> 结果返回来进行。如下是示例代码

const express = require('express')
const Message = require('../utils/Message')
const pool = require('../utils/Connection')
const router = express.Router();
// 1. 查询
router.get('/findAll', (req, resp) => {
let sql = "select * from tbl_student"
// 获取连接
pool.getConnection((err, connection) => {
if (err) throw err;
// 查询
connection.query(sql, function (error, results, fields) {
if (error) throw error;
// 释放
connection.release(); resp.send(Message.success(results));
});
})
})
// 2. 删除
router.delete('/deleteById', (req, resp) => {
let id = req.query.id;
let sql = "delete from tbl_student where id = " + id;
pool.getConnection((err, connection) => {
if (err) throw err; connection.query(sql, (error, results) =>
{
if (error) throw error; connection.release();
resp.send(Message.success('删除成功'))
})
})
})
// 3. 保存或更新
router.post('/saveOrUpdate', (req, resp) => {
let stu = req.body;
let sql = "insert into tbl_student(id,name,gender,birth)
values(null," + stu.name + "," + stu.gender + "," + stu.birth +
")"
if (stu.id) {
sql = "update tbl_student set name = '" + stu.name +
"',gender='" + stu.gender
}
pool.getConnection((err, connection) => {
if (err) throw err; connection.query(sql, (error, results) =>
{
if (error) throw error; connection.release();
resp.send(Message.success('操作成功!'))
})
})
})

2.5 前端开发

前端开发依旧使用vue + axios + elementui来进行

<!DOCTYPE html>
<html lang="en">
<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>学生选课</title>
<!-- axios -->
<script
src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.1/axios.min.js"
></script>
<!-- vue -->
<script
src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.12/vue.min.js">
</script>
<!--elementui -->
<!-- 引入样式 -->
<link rel="stylesheet" href="https://unpkg.com/element-
ui/lib/theme-chalk/index.css">
<!-- 引入组件库 -->
<script src="https://unpkg.com/element-ui/lib/index.js">
</script>
</head>
<body>
<div id="app">
<h2> {{name}}</h2>
<el-button @click="loadStudents" size="small" type="primary">
刷新</el-button>
<el-button @click="toSave" size="small" type="primary">录
入</el-button>
<!-- 表格 -->
<el-table :data="students" size="small">
<el-table-column prop="name" label="姓名"></el-table-column>
<el-table-column prop="gender" label="性别"></el-table-
column>
<el-table-column prop="birth" label="生日"></el-table-
column>
<el-table-column label="操作" width="100" align="center">
<template v-slot="scope">
<el-button type="text" size="mini"
@click="toDelHandler(scope.row)">
删除
</el-button>
<el-button type=" text" size="mini"
@click="toEditHandler(scope.row)">
修改
</el-button>
</template>
</el-table-column>
</el-table>
<!-- 表格 -->
<!-- 模态框 -->
<el-dialog :title="title" :visible.sync="visible"
width="50%">
<el-form :model="form" size="small" label-width="80px">
<el-form-item label="姓名">
<el-input v-model="form.name"></el-input>
</el-form-item>
<el-form-item label="性别">
<el-radio-group v-model="form.gender">
<el-radio label="男" value="男"></el-radio>
<el-radio label="女" value="女"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="出生日期">
<el-date-picker v-model="form.birth" value-
format='timestamp' type="date" placeholder="选择日期">
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button@click="visible=false"size="small">取 消</el-
button>
<el-button type="primary" @click="submitHandler"
size="small">确 定</el-button>
</span>
</el-dialog>
</div>
<script>
new Vue({
el: "#app",
data: {
name: "学生管理",
students: [],
visible: false,
form: {},
title: "录入学生信息"
},
created() {
this.loadStudents();
},
methods: {
toDelHandler(row) {
this.$confirm('此操作将永久删除该数据, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
let url = "http://localhost:3000/student/deleteById"
axios.delete(url, {
params: { id: row.id }
}).then((resp) => {
this.$message({ type: 'success', message:
resp.data.message })
this.loadStudents();
})
})
},
toEditHandler(row) {
this.title = "修改学生信息"
this.form = { ...row }
this.visible = true;
},
submitHandler() {
let url = "http://localhost:3000/student/saveOrUpdate";
axios.post(url, this.form).then(resp => {
this.$message({ type: 'success', message:
resp.data.message })
this.loadStudents();
this.visible = false;
})
},
toSave() {
this.title = "录入学生信息"
this.form = {}
this.visible = true;
}, loadStudents() {
let url = "http://localhost:3000/student/findAll"
axios.get(url).then(resp => {
this.students = resp.data.data;
})
}
}
})
</script>
</body>
</html>