koa mysql模块,(三)koa+mysql 实现MVC模式

这个系列第一篇介绍了如何安装 mysql,以及使用 Node.js 连接数据库;第二篇实现了基本的数据库新增查找修改删除操作,但是没有实现后端 MVC 架构模式,随着项目需求加大,逻辑复杂度提高,这种没有模块划分,依赖解耦的代码组织是极其不易扩展的,所以我们重新组织一下项目架构,实现软件业务和显示分离的 MVC 模式。

MVC 模式

首先来认识一下 MVC 是什么?

根据 MDN上 的定义:MVC(Model-View-Controller)是一种软件设计模式,它强调分离软件的业务逻辑和显示,这种分离提供了更好的分工和改进的维护。一些其他的模式也是基于MVC来设计的,像MVVM(Model-View-Viewmodel),MTP(Model-View-Presenter),MVW(Model-View-Whatever)。

对 MVC 软件设计模式的三个部分可以被描述如下:

Model:模型持有所有的数据,状态和程序逻辑(只关注与数据相关的逻辑)

View:负责界面的布局和显示;

Controller:负责模型和界面之间的交互;

我的理解是 Model 只要关注数据,数据从哪里来,比如一个查询记录,需要从数据库中查询,那此时的 Model 只是做数据查询并返回数据的工作,至于页面需要什么的数据结构,就需要 Controller 这一层来做逻辑的处理,然后将数据给到 View 层做显示。View 层收集用户数据给到 Controller 做处理,提供给 Model 来写入或读取数据。

这里我们先抛开 View 层,因为针对现在的前后端分离的模式,前端衍生了独立的 MVVM 模式来专注于数据和交互。我把前端的这一层归做 View 层。这里的 View 层只需要前端构建之后的静态资源即可。这样前端可以有多种实现方式,比如现在的三大框架。

后端跟前端的通过接口进行交互,我们把接口地址独立成后端路由,作为一个可扩展的部分,所以针对 server 端,将其分为 Model(模型),Controller(控制器),Route(路由)模式的项目结构。

实现

之前是把全部的路由,逻辑处理,从数据库中读取数据全都放在 index.js 里面,随着工程的复杂,不易扩展和维护。现在我们一步步实现 MVC 模式。

Model 层

先处理 Model 层,然后是 Controller 层,最后的路由层 Route 需要依赖 Controller 层来做。

在 server 目录下新建一个 models 文件夹用来放各个模块的 model,新建 listModel.js 的文件来放这个模块的数据相关的操作,代码如下:

// server/models/listModel.js

const { query } = require('../db')

const userModel = {

async getListModel(ctx){

let result = await query('SELECT * FROM domain;');

return result;

},

async addModel(ctx){

let result = await query('INSERT INTO domain SET ?', JSON.parse(ctx.request.body));

return result.insertId;

},

async deleteModel(ctx){

await query('DELETE FROM domain where id=' + JSON.parse(ctx.request.body).id);

},

async updateModel(ctx){

const postData = ctx.request.body;

const pdata = JSON.parse(postData);

await query('UPDATE domain SET name = ?, status = ? WHERE id = ?;', [pdata.name, pdata.status, pdata.id]);

},

async getinfoModel(ctx){

let info = await query('SELECT * FROM domain WHERE id = ?;', ctx.params.id);

return info;

}

}

module.exports = userModel;

这个文件主要是将之前在 index.js 的访问数据库的操作提取出来,分离出项目逻辑,只做单纯的数据存取操作,然后将数据提供给 Controller 层来做逻辑和数据结构输出。这里需要传入全局的ctx上下文,来拿到请求参数。

Controller 层

在 server 目录下新建一个 controllers 文件夹用来放各个模块的 controller,新建 list.js 的文件来这个模块的数据相关的逻辑操作,主要是提取数据,处理数据,响应数据格式,这一块的数据来源就是 Model 层提供,代码如下:

const { getListModel, addModel, deleteModel, updateModel, getinfoModel } = require('../models/listModel')

const listController = {

// 获取表数据

async getListController(ctx, next){

let result = await getListModel(ctx);

let list = [];

result.forEach(item => {

list.push({

id: item.id,

name: item.name,

status: item.status

})

});

console.log(list);

ctx.body = {

code: 200,

data: list,

message: 'getList success'

};

},

// 添加一条记录

async addController(ctx, next){

let insertId = await addModel(ctx);

ctx.body = {

code: 200,

data: {

id: insertId

},

message: 'add success'

};

},

// 删除一条记录

async deleteController(ctx, next){

await deleteModel(ctx);

ctx.body = {

code: 200,

data: [],

message: 'delete success'

}

},

// 修改数据

async updateController(ctx, next){

await updateModel(ctx);

ctx.body = {

code: 200,

data: [],

message: 'update success'

}

},

// 获取记录详细信息

async getinfoController(ctx, next){

let result = await getinfoModel(ctx);

ctx.body = {

code: 200,

data: result[0],

message: 'getInfo success'

};

}

}

module.exports = listController;

Route 路由层

在server目录下新建routes文件夹,这个文件夹下放置路由和子路由,现在我们建一个总路由文件route.js,这里面主要做注册子路由/api,代码如下:

const Router = require('koa-router')()

//导入子路由

const api = require('./api')

// 注册子路由

Router.use('/api', api.routes(), api.allowedMethods());

module.exports = Router

子路由可以根据模块划分,比如用户中心的 user ,或者文章列表 article,现在我们新建一个/api的子路由,api.js 代码如下:

// server/routes/api.js

const router = require('koa-router')()

const { getListController, addController, deleteController, updateController, getinfoController } = require('../controllers/list')

const routers = router

.get('/getList', getListController)

.post('/add', addController)

.post('/delete', deleteController)

.post('/update', updateController)

.get('/getInfo/:id', getinfoController)

module.exports = routers;

前端访问的路由地址就是/api/getList等,服务器监听到路由进来之后,就会触发 Controller,接口返回数据。

现在入口 index.js 文件已经被瘦身,将之前的逻辑全部移到 controller 层处理,数据读取移到 model 层,这里只做全局路由注册,代码如下:

const Koa = require('koa');

const static = require('koa-static');

const { join } = require('path');

const koaBody = require('koa-body');

const app = new Koa();

const routers = require('./routes/index')

const staticPath = '../static';

app.use(koaBody());

app.use(static(

join(__dirname, staticPath)

));

app.use(routers.routes()).use(routers.allowedMethods());

app.listen(4455);

console.log('listen at 4455');

记住前端的访问路径一定要变。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值