• Node.js连接MySQL数据库及构造JSON的正确姿势


    做一下整理,以前也很随意的引入包链接数据库,后来发现常常连接出问题,异常退出,后来使用在网上一个方法解决问题,网址由于书签丢失,抱歉不能引用了。再有就是简单的模块化下,使得目录合理点,再有就是说明一下,标题有赚眼球的嫌疑,代码我这里使用正常,而且我觉得也蛮好用,不过不代表真的就是该这么写,毕竟我还是个node菜鸟,大神路过有更好的方式方法,还请留下脚印,感激不尽!

    Node版本:v0.10.34

    Express版本:4.9.0

    在继续进行之前,假设你搭建的本地环境已经可以看到这个界面:

    --------------------------------------------------------------------------------------------------------

    好了,继续进行。首先,看一下我的目录:

    controllor目录和setting.js是新建的,下面放些处理功能,比如操作数据库的database.js,和用于处理数据,返回JSON的dd_tongji.jssettings.js用于存储一些配置信息

    如果新建的工程,那么需要在路由(routers/index.js)中添加两行代码来引入我们的模块和配置URL

    var express = require('express');
    var router = express.Router();
    var dd_tongji = require('../controller/dd_tongji.js'); //引入自定义模块
    
    /* GET home page. */
    router.get('/', function(req, res) {
      res.render('index', { title: 'Express' });
    });
    
    router.get('/data', dd_tongji.get_click); //配置RUL,访问http://localhost:3000/data
    
    module.exports = router;

    然后添加如下代码到controller/dd_tongji.js

    exports.get_click = function(req, res) {
      return res.jsonp({"hello":"world"});
    };

    重启服务后访问:http://127.0.0.1:3000/data

    这样,后端的工作就是这样了,前台访问这个网址就可以获取数据了~

    - 说好的数据库呢?说好的构造JSON呢?

    - 别急,且往下看

    ----------

    (一)Node.js连接MySQL数据库

    dd_tongji.js中我们想引入MySQL中的数据,处理成我们想要的JSON格式,好,来看下database.js中的内容:

    var mysql = require('mysql'),
        settings = require('../settings');
    
    module.exports.getConnection = function () {
        if ((module.exports.connection) && (module.exports.connection.socket) && (module.exports.connection._socket.readable) && (module.exports.connection._socket.writable)) {
            return module.exports.connection;
        }
        console.log(((module.exports.connection) ? "UNHEALTHY SQL CONNECTION; RE" : "") + "CONNECT TO SQL.");
        var connection = mysql.createConnection({
                host: settings.mysql.host,
                port: settings.mysql.port,
                database: settings.mysql.database,
                user: settings.mysql.user,
                password: settings.mysql.password,
                charset: "utf8"
        });
        connection.connect(function (err) {
                if (err) {
                    console.log("SQL CONNECT ERROR: ", err);
                } else {
                    console.log("SQL CONNECT SUCCESSFUL.");
                }
        });
        connection.on("close", function(err) {
                console.log("SQL CONNECTION CLOSED.");
        });
        connection.on("error", function(err) {
                console.log("SQL CONNECTION ERROR: ." + err);
        });
        module.exports.connection = connection;
        return module.exports.connection;
    };
    
    module.exports.getConnection();

    数据库的配置信息在settings.js中,我们已经通过settings = require('../settings');引入

    看下settings.js的内容:

    module.exports = {
    mysql: {
              host: '127.0.0.1',
              port: 3306,
              user: 'user',
              password: '123456',
              database: 'mydata'
           }
    }

    dd_tongji.js中使用引入(部分代码)

    var connection = database.getConnection();
    connection.query(sql, function(err, rows, fields) {
      ...//rows为查询出的数据,可通过rows[i].字段 访问数据
    }

    因为这里先说明的是引入数据库,所以完整的dd_tongji.js代码在构造JSON的时候再书写

    而且这种方式貌似是不需要关闭连接的。(忘了为什么了,抱歉...)

    好了,数据库部分先暂时这样,一会儿会有示例演示取数据,拼接JSON,并返回。

    (二)Node.js构造JSON

    假使URL接口是http://127.0.0.1:3000/data?genus=DEFAULT&evt=ABOUT&begin=2014-09-09&end=2014-09-20

    那么也就是说我们需要查询的数据就是数据库genus字段为DEFAULT,ent字段为ABOUT,日期为2014-09-09到2014-09-20期间的数据

    看一下新的dd_tongji.js代码:

    var database = require('./database')
    
    /* 传入字符串获取间隔的天数 */
    function DateDiff(sDate1, sDate2){ //sDate1和sDate2是2002-12-18格式
      var aDate, oDate1, oDate2, iDays
      aDate = sDate1.split("-")
      oDate1 = new Date(aDate[1] + '-' + aDate[2] + '-' + aDate[0]) //转换为12-18-2002格式
      aDate = sDate2.split("-")
      oDate2 = new Date(aDate[1] + '-' + aDate[2] + '-' + aDate[0])
      iDays = parseInt(Math.abs(oDate1 - oDate2) / 1000 / 60 / 60 /24) //把相差的毫秒数转换为天数
      return iDays
    }
    
    /* 根据参数返回日期的字符串 */
    function GetDateStr(BeginDate, AddDayCount) {
      var begin = Date.parse(BeginDate);
      var dd = new Date(begin);
      dd.setDate(dd.getDate()+AddDayCount);//获取AddDayCount天后的日期
      var y = dd.getFullYear();
      var m = dd.getMonth()+1;//获取当前月份的日期
      var d = dd.getDate();
      if(m<10) m = '0' + m;
      if(d<10) d = '0' + d;
      return y + "-" + m + "-" + d;
    }
    
    exports.get_click = function(req, res) {
    
      // console.log(DateDiff(req.query.begin, req.query.end));
    
      // 构造日期列表
      var datelist = []
      var BeginDate = req.query.begin;
      var EndDate = req.query.end;
      var DateNum = DateDiff(BeginDate, EndDate) + 1; // 需要查询的日期天数
      for (var i=0; i<DateNum; i++) {
        time = GetDateStr(BeginDate, i);
        datelist.push(time)
      }
    
      console.log(datelist);
      console.log(datelist.length);
    
      // data 用于保存查询到的数据
      var data = {};
     
      for(var i=0; i< datelist.length; i++) {
        data[datelist[i]] = {
          click_num: 0,
          people_num: 0,
          average_num: 0
        }
      }
    
      // 定义查询语句
      var sql = "SELECT * FROM click WHERE genus='" + req.query.genus + "' AND evt='" + req.query.evt + "' and date>='" + req.query.begin + "' and date <='" + req.query.end + "'"
      console.log(sql);
    
      // 连接数据库
      var connection = database.getConnection();
      connection.query(sql, function(err, rows, fields) {
        if (err) throw err;
    
        for(var i=0; i < rows.length; i++) {
          data[rows[i].date] = {
            click_num: rows[i].click_num,
            people_num: rows[i].people_num,
            average: rows[i].average
          }
        }
    
        var result = {
          genus: req.query.genus,
          evt: req.query.evt,
          data: data
        }
    
        return res.jsonp(result);
      });
    };

    不多讲解了,例子还是很好理解的,data初始化操作是为了填补有些日期没有数据的问题。

    来看下数据库中的表结构和JSON的结果

    OK,可以了,如果大家发现我写的哪里有问题,记得通知我哦,感激不尽

  • 相关阅读:
    EF中,保存实体报错:Validation failed for one or more entities. 如何知道具体错误在哪?
    个人常用的移动端浅灰底index.html
    分享一段js,判断是否在iPhone中的Safari浏览器打开的页面
    2017年3月25日,祝自己23岁生日快乐!
    JavaScript监控页面input输入整数且只能输入2位小数
    iPhone IOS10安装APP没提示连接网络(无法联网)的解决办法
    iPhone屏蔽IOS更新、iPhone系统更新的提示(免越狱,有效期更新至2021年)
    iPhone Anywehre虚拟定位提示“后台服务未启动,请重新安装应用后使用”的解决方法
    C# OracleDBhelper
    戴尔灵越15-5000/3558等系列修改BIOS设置U盘启动
  • 原文地址:https://www.cnblogs.com/ishell/p/4194280.html
Copyright © 2020-2023  润新知