Node教程——更新干货!如何在Node封装mysql的DAO层
具体的代码实例,我已经上传到github,欢迎fork还有补充
概述DAO层的封装
- 首先我们拿JDBC的DAO层来举例子
DAO(Data Access Object) 是数据访问层
Action像是服务员,顾客点什么菜,菜上给几号桌,都是ta的职责;Service是厨师,action送来的菜单上的菜全是ta做的;Dao是厨房的小工,和原材料(通过hibernate操作数据库)打交道的事情全是ta管。
对象的调用流程:JSP—Action—Service—DAO—Hibernate(某框架)—数据库。
- 我们来谈谈Node的DAO层封装那些事
基于我目前的开发项目的架构,从数据的流转来看,它类似于下面这个样子
Model(数据模型)– Middleware(数据处理中间件) — Router(路由处理)
这一讲我们主要是关注与Model层的处理,既,如果更加简单更加精确的的把数据查询出来
关于Node for MYSQL的DAO封装
基础的知识,我们这里不讲,我们直接考虑如何在项目中使用
-
首先我们npm mysql,这个没有什么好解释的
-
开始封装一个最基础的通用的数据链接类
要在node中操作mysql,一般有如下的事情要做
基础的使用我就不讲了,我们直接用单例模式来进行封装成一个类
[model/DAO/model.js]
const mysql = require('mysql')
/**
* 数据模型的基类
* 封装了数据库操作
*/
module.exports = class Model {
// 连接对象
static conn = null
/**
* 初始化数据连接操作
*/
static connection() {
Model.conn = mysql.createConnection({
host: '127.0.0.1',
user: 'root',
password: '123',
database: 'blog'
})
Model.conn.connect(err => {
if (err) {
console.log(`数据库连接失败:${err.message}`)
}
})
}
/**
* 关闭数据库连接,注意,你需要及时的关闭查询数据流,比秒消耗性能
*/
static end() {
if (null != Model.conn) {
Model.conn.end()
}
}
/**
* 通用查询方法
* @param {string} sql 要执行的SQL语句
* @param {Array} params 给SQL语句的占位符,以后由具体的Model决定具体的传入参数
*/
static query(sql, params = []) {
return new Promise((resolve, reject) => {
this.connection()//调用连接
//开始查询
Model.conn.query(sql, params, (err, results) => {
if (err) {
reject(err)
} else {
resolve(results)
}
})
//关闭流
this.end()
})
}
}
- 具体的业务查询的实现
这里我们假设我的表里面有这些字段,我们具体的业务就是在这里构造查询条件然后就可以去展开具体的查询了,注意继承
[model/articel.js]
const Mysql = require('./DAO/model');
//开始实现具体的查询Model
module.exports = class Article extends Mysql {
/**
* 描述 查询所有的列表,这里是SQL的具体的实现方法,根据以往需求来处理
* @date 2020-04-29
* @returns {any} 返回值是查询出来的数据对象
*/
static getList() {
return new Promise((resolve, reject) => {
let sql = 'SELECT id,title,content,`time`,thumbnail FROM article ORDER BY TIME DESC'
this.query(sql).then(results => {//调用父类的查询方式
resolve(results)
}).catch(err => {
console.log(`获取文章列表失败:${err.message}`)
reject(err)
})
})
}
/**
* 获取指定文章的详情
* @param {integer} id 文章编号
*/
static getArticleById(id) {
return new Promise((resolve, reject) => {
let sql = 'SELECT a.id,a.title,a.content,a.`time`,a.hits,a.`category_id`,c.`name`,a.`thumbnail`,a.`hot` FROM article a,category c WHERE a.`category_id` = c.`id` AND a.id = ?'
this.query(sql, id).then(results => {//调用父类的查询方式
resolve(results[0])
}).catch(err => {
console.log(`获取指定文章的详情失败:${err.message}`)
reject(err)
})
})
}
}
然后呢?如何使用?具体的node项目中,需要说明的,以上的两端代码 在node中,都是处于Model下的,有了model使用就相对比较简单了,
router( 调用中间件mideelwear )— middleware(接受到router的需求开始调用模型层拿数据) –以req方式,丢回给router,router反过来拿数据去渲染或者做成API接口就可以了
[router/index.js]
+++
const Articel = require('../middelwear/article')
+++
articleApp.get('/:id', [Articel.getArticleById], (req, res) => {
let { article } = req//由于我们之前的中间件已经把结果存到了req里面,这样我们就能直接拿了
//如果是模板渲染可以这样来干
// res.render('article', { article: article })//如果你需要做API接口于是乎你可以以JSON形式丢出去
res.send( JSON.stringify( { article: article } ) )
})
[middleware/articel.js]
//如果数据是从 路由Router过来
function getArticleById (req, res, next) {
//然后再路由里,我只需要这样用就行了,直接从req里面解构过来,需要说明一些
// let id = req.params.id,这个用于处理get /:?这样的数据,?的具体数据,就能从req.params里面弄出来
// let id = req.body,这个用于处理POST这样的数据,具体数据,就能从req.body里面弄出来
let id = req.params.id
Article.getArticleById(id).then(results => {
req.article = results
next()//放行
}).catch(err => {
next(err)
})
}
以上就是最基础的Node for Mysql数据的DAO层的封装,这样一来,后面的数据操作,就变得简单的多了,希望我的文章对你有所帮助!~~~,接下里我会封装一个关于MongDB的DAO层,请大家期待