项目需求:
1. 数据库采用mysql实现, 后台服务Koa2框架, 通过postman调试所有接口
2. 接口功能:
(1)实现对科目表的增删改查
(2)实现对试题表的增删改
(3)实现对试题表的查询操作,要求:<1>显示科目名称和类型名称 <2> 可以按照科目名称、题目进行模糊查询 <3> sql语句中使用占位符
1.建立数据库
2.后台
(1)搭建koa2框架并配置
项目初始化 npm init -y
安装 npm i koa -g
使用脚手架的方式安装 npm install -g koa-generator
创建项目 koa2 koapro[koapro 项目名称]
配置前的项目启动 npm start koapro 或 npm run start
(2)连接数据库
config/sqlconfig.js 配置数据库相关信息
// mysql数据库配置
const sqlconfig = {
host: 'localhost', // 连接地址
user: 'root', //用户名
password: '****', //密码
port: 3306 , //端口号
database: 'mysql02_exam' //数据库名
}
module.exports = sqlconfig
utils/mysqlUtils.js 创建连接池,连接数据库 (不要忘记下载 mysql 模块啊~~~)
// 连接数据库
const mysql = require('mysql')
const sqlconfig = require('../config/sqlconfig')
// 创建连接池
const pool = mysql.createPool(sqlconfig)
// 连接
const exec = (sql,values) => {
return new Promise((resolve, reject) => {
pool.getConnection((err, conn) => {
if (err) {
//连接错误
reject(err)
} else {
//连接成功
conn.query(sql,values, (err, data) => {
if (err) {
//操作失败
reject(err)
} else {
resolve({
code: 0,
message: '操作成功!',
data,
})
}
})
}
// 当连接不再使用时,归还到连接池
conn.release()
})
})
}
module.exports = {
exec
}
(3)创建相关路由
routes/subject.js 科目
const { searchList,delList,updateList,addList } = require('../control/control')
const router = require('koa-router')()
// 设置路由前缀
router.prefix('/subject')
// 查询
router.get('/search', async (ctx, next) => {
await searchList(ctx,'subject')
})
// 修改
router.post('/update', async (ctx, next) => {
await updateList(ctx,'subject')
})
//增加
router.post('/add', async (ctx, next) => {
await addList(ctx,'subject')
})
// 删除
router.post('/delete', async (ctx, next) => {
await delList(ctx,'subject')
})
module.exports = router
routes/examquestion.js 试题
const { searchList,delList,updateList1,addList, } = require('../control/control')
const router = require('koa-router')()
router.prefix('/examquestion')
// 查询
router.get('/search', async (ctx, next) => {
await searchList(ctx,'examquestion')
})
// 修改
router.post('/update', async (ctx, next) => {
await updateList1(ctx,'examquestion')
})
//增加
router.post('/add', async (ctx, next) => {
await addList(ctx,'examquestion')
})
// 删除
router.post('/delete', async (ctx, next) => {
await delList(ctx,'examquestion')
})
module.exports = router
别忘啦, 要在app.js中引入和挂载路由喔~~~
const subject = require('./routes/subject')
const examquestion = require('./routes/examquestion')
// routes
app.use(subject.routes(), subject.allowedMethods())
app.use(examquestion.routes(), examquestion.allowedMethods())
(4)封装操作数据库函数
control/control.js
因为很多操作基本一样, 所以大部分我就只写了一个方法, 多处路由调用,根据表名进行相关操作
const {exec} = require('../utils/mysqlUtils')
const { randomInt } = require('crypto')
const moment = require('moment')
// 查询
const searchList = async(ctx, table)=>{
var params = []
if(table === 'subject'){
var sql = ` select * from ${table} where 1=1`
// 获取get请求的参数
const {sid, sname} = ctx.query
// 如果存在sid
if(sid && sid.trim() !== ''){
sql += ` and sid = ? `
params.push(`${sid}`)
}
// 如果存在sname 可模糊查询
if(sname && sname.trim() !== ''){
sql += ` and sname like ? `
params.push(`%${sname}%`)
}
}
if(table === 'examquestion'){
var sql = ` SELECT ? FROM 'subject' s ,testtype t ,examquestion e, exampaper_testquestion et WHERE et.qid = e.qid AND et.tid = t.tid `
// 获取get请求的参数
const { sname, title } = ctx.query
console.log(ctx.query);
if(ctx.query === 'undefined'){
console.log(ctx.query.length);
sql = ` SELECT s.sname, t.tname FROM subject s ,testtype t ,examquestion e, exampaper_testquestion et WHERE et.qid = e.qid AND et.tid = t.tid `
}
if(ctx.query !== 'undefined'){
console.log(ctx.query.length);
sql = ` SELECT s.sname, t.tname FROM subject s ,testtype t ,examquestion e, exampaper_testquestion et WHERE et.qid = e.qid AND et.tid = t.tid `
// 如果存在sname 可模糊查询
if(sname && sname.trim() !== ''){
sql += ` and sname like ? `
params.push(`%${sname}%`)
}
if(title && title.trim() !== ''){
sql += ` and title like ? `
params.push(`%${title}%`)
}
}
}
const result = await exec(sql,params)
if(result.data.length > 0){
ctx.body = {
code : 1,
message: "查询成功",
result
}
}else{
ctx.body = {
code : 0,
message: "查询失败",
}
}
}
// 删除
const delList = async(ctx, table)=>{
let id = table === 'subject' ? 'sid' : 'qid'
// 根据id删除数据 一次可删多个
let sql = ` delete from ${table} where ${id} in (?) `
// 获取post请求的参数
const {ids} = ctx.request.body
console.log(ids);
// 有删除id
if(ids && ids.length > 0){
// sids本身为数组, 一个?只要一个元素
const result = await exec(sql,[ids])
console.log(sql,[ids]);
console.log(result);
if(result.data.affectedRows > 0){
ctx.body = {
code : 1,
message: "删除成功",
result
}
}else{
ctx.body = {
code : 0,
message: "删除失败",
}
}
}else{
ctx.body = {
code :-1,
message: "未输入删除id",
}
}
}
//更新
const updateList = async(ctx, table)=>{
// 获取post请求的参数
const {sid, sname} = ctx.request.body
// 根据id修改相关信息
let sql = ` update ${table} set sid = sid `
let params = []
// 如果存在sname
if(sname && sname.trim() !== ''){
sql += ` , sname = ? `
params.push(sname)
sql += ` where sid = ${sid} `
params.push(sid)
const result = await exec(sql,params)
console.log(result);
if(result.data.affectedRows > 0){
ctx.body = {
code : 1,
message: "修改成功",
result
}
}else{
ctx.body = {
code : 0,
message: "修改失败",
}
}
}else{
ctx.body = {
code :-1,
message: "未输入更新的sname",
}
}
}
const addObj = (obj,table) => {
if(table === 'subject'){
let { sname = ''} = obj;
// 随机生成 sid randomInt(x)返回0~x的随机整数
const sid = moment().get() + (randomInt(999) + 1) + '';
return Array.of(sid,sname);
}
if(table === 'examquestion'){
let { title,sid,tid,answer,optiona,optionb,optionc,optiond} = obj;
// 随机生成 qid randomInt(x)返回0~x的随机整数
const qid = moment().get() + (randomInt(999) + 1) + '';
return Array.of(qid,title,sid,tid,answer,optiona,optionb,optionc,optiond);
}
}
// 增加
const addList = async(ctx,table)=>{
let { data } = ctx.request.body
console.log(data);
let values = []
// 检测data是否为数组
if(Array.isArray(data)){
// 是数组, 则对每一项进行操作
values = data.map(item => addObj(item,table) )
}else {
// 对象
values= addObj(data,table);
}
let sql = ''
if(table === 'subject'){
// sql语句中 ? 为占位符, 表该处有内容, 具体是什么,后边传值, 所传数据(数组中的元素)的个数必须要和占位符的个数一样, 要以数组的形式进行传递(不论有几个元素)
sql = ` insert into subject(sid,sname) values (?) `
}
if(table === 'examquestion'){
// sql语句中 ? 为占位符, 表该处有内容, 具体是什么,后边传值, 所传数据(数组中的元素)的个数必须要和占位符的个数一样, 要以数组的形式进行传递(不论有几个元素)
sql = ` insert into examquestion(qid,title,sid,tid,answer,optiona,optionb,optionc,optiond) values (?) `
}
console.log(sql);
const result = await exec(sql,[values])
console.log(result);
if(result.data.affectedRows > 0){
ctx.body = {
code : 1,
message: "添加成功",
result
}
}else{
ctx.body = {
code : 0,
message: "添加失败",
}
}
}
//更新
const updateList1 = async(ctx, table)=>{
// 获取post请求的参数
const keys = Object.keys(ctx.request.body)
const val = Object.values(ctx.request.body)
let sql = ''
let items = []
keys.forEach((item, index) => {
items.push(`${item} = '${val[index]}'`)
})
sql = `update ${table} set ${items} where qid = '${ctx.request.body.qid}'`
const result = await exec(sql,'')
console.log(result);
if(result.data.affectedRows > 0){
ctx.body = {
code : 1,
message: "修改成功",
result
}
}else{
ctx.body = {
code : 0,
message: "修改失败",
}
}
}
module.exports = {
searchList,
delList,
updateList,
addList,
updateList1
}
源码我放在资源里啦, npm i就好啦
https://download.csdn.net/download/qq_54379580/87452023
PreviousNotes:
https://blog.csdn.net/qq_54379580/article/details/128995535