zl程序教程

您现在的位置是:首页 >  后端

当前栏目

Nodejs搭建真正与数据库交互的服务器

Nodejs数据库服务器 搭建 交互 真正
2023-09-11 14:16:32 时间

0.下载MySQL、熟悉最基本的命令

查询命令:select * from blog、select * from blog where id=1

插入命令:INSERT INTO blog (title,content,author,createAt) VALUES ('标题2','内容2','是RYN',0000567890000)

更新命令:update blog set title='标题1',content='内容1' where id=1

删除命令:delete from blog where id=1

1.创建服务器

在空文件夹下的端口执行:npm init -y,会生成package.json文件

创建文件夹bin,并在文件夹下创建www.js文件,在此文件里创建服务器

const http=require('http')
const serverHandler=require('../app.js')
const POST=5000
const server=http.createServer(serverHandler)
server.listen(POST,()=>{
    console.log("正在监听5000端口。。。")
})

2.连接数据库、创建执行函数

设置数据库的root和password以后,创建myblog数据库,在库中创建blog表

node.js连接数据库的配置(src下新建db文件夹,在里面新建的mysql.js写):

const mysql = require('mysql')

//创建连接对象
const connection = mysql.createConnection({
    host: 'localhost',
    user: 'root',
    password: '123456',
    port: 3306,
    database: 'myblog'
});

connection.connect()

//执行sql语句,异步执行,返回promise对象
function execSQL(sql) {
    return new Promise((reslove, reject) => {
        connection.query(sql, (err, result) => {
            if (err) {
                reject(err)
                connection.end()
                return
            }
            reslove(result)
            connection.end()
        })
    })
}


module.exports = {
    execSQL,
}

3.定义五种请求响应函数。

controllers中的blogs.js文件是与数据库交互的文件,所以执行sql语句的代码写在这里,将原本返回的假数据删除,真正与服务器交互:

引入执行函数:exeSQL

注意,.then函数返回的是新的promise对象,其状态和内容受到里面返回值的影响。所以想把执行结果返回,外面还需要加一个return,将这个新的promise返回。

const { execSQL } = require('../db/mysql')
const getList = (author, keyword) => {
    const sql = `select * from blog`
    return execSQL(sql)//返回的是promise对象
}

const getDetail = (id) => {
    let sql=`select * from blog where id=${id}`
    return execSQL(sql)
}

const newBlog = (content) => {
    console.log(content)
    let sql=`INSERT INTO blog (title,content,author,createAt) VALUES ('${content.title}','${content.content}','${content.author}','${content.createAt}')`
    return execSQL(sql).then((res)=>{
        return res.insertId
    })
}

const upData = (id,content) => {
    let sql=`update blog set title='${content.title}',content='${content.content}' where id=${id}`
    return execSQL(sql).then((res)=>{
        if(res.affectedRows>0){
            return true
        }
        return false
    })
}

const Delete = (id) => {
    let sql =`delete from blog where id=${id}`
    return execSQL(sql).then((deleteRes)=>{
        if(deleteRes.affectedRows>0)return true
        return false
    })
}

module.exports = {
    getList,
    getDetail,
    newBlog,
    upData,
    Delete
}

4.配置路由

routes/blog.js中,对controllers/blogs.js返回的内容进行成功或者失败的包装,

const {getList,getDetail,newBlog,upData,Delete}=require('../controllers/blog')
const {SuccessModel, ErrorModel}=require('../model/responseModel')
const querystring=require('querystring')
const { resolve } = require('path')


//对路由进行合适的处理,返回合适的数据
const handleBlogRoute=(req,res)=>{
    const method=req.method
    const url=req.url
    const path=url.split("?")[0]
    const query=querystring.parse(url.split("?")[1])
    
    if(method==='GET'&&path=="/api/blog/list"){
        //!!! promise.then()返回一个新的promise(这就是.then能链式调用的原因)
        // 如果抛出异常:新的promise变为rejected,reason为抛出的异常
        // 如果返回的是非promise的任意值,新的promise变为resolved,value为返回的值
        // 如果返回的是另一个新的promise,此promise的结果就成为新promise的结果
        //因此,此处的返回结果是Promise{ SuccessModel {data:[],errno:0}}
        return getList(query.author||"",query.keyword||"").then((blogList)=>{ 
            return new SuccessModel(blogList)
        })
    }

    if(method==='POST'&&path=="/api/blog/detail"){
        return getDetail(query.id||NaN).then((detailContent)=>{
            if(detailContent){
                return new SuccessModel(detailContent)
            }
            return new ErrorModel(detailContent)
        })
        
    }
    if(method==='POST'&&path=="/api/blog/new"){
        return newBlog(req.body).then(res=>{
            return new SuccessModel(res)
        }) 
    }
    if(method==='POST'&&path=="/api/blog/updata"){
        return upData(query.id,req.body).then((ifUpdataSucceed)=>{
            if(ifUpdataSucceed) return new SuccessModel("更新成功")
            return new ErrorModel("更新失败")
        })
        
    }
    if(method==='POST'&&path=="/api/blog/delete"){
        return Delete(query.id).then((ifDeleteSuccess)=>{
            if(ifDeleteSuccess)return new SuccessModel("删除成功")
            return new ErrorModel("删除失败")
        })
    }
}
module.exports=handleBlogRoute

5.app.js对routes/blog.js返回的promise进行解析与响应修改

const serverHandler=(req,res)=>{
    res.setHeader('Content-type','application/json')

    getPostData(req).then((postData)=>{
        //postData是浏览器发送来的数据
        req.body=postData

        const blogDataPromise = handleBlogRoute(req, res)//将路由处理的结果保存在blogData里
        if (blogDataPromise) {
            blogDataPromise.then((blogData)=>{
                res.end(JSON.stringify(blogData))
            }) 
            return
        }
        //请求的不在我们处理范围内,返回文本内容,“404 not found”
        res.writeHead(404, { 'Content-Type': 'text/plain' })
        res.write("404 not found")
        res.end()
})
}