zoukankan      html  css  js  c++  java
  • 零代码第一步,做个添加数据的服务先。node.js + mysql

    node.js + mysql 实现数据添加的功能。万事基于服务!

    增删改查之添加数据。

    优点:只需要设置一个json文件,就可以实现基本的添加功能,可以视为是零代码。

    添加数据的服务实现的功能:

    1、  添加一条记录、多条记录(批量添加)、主从表记录

    2、  记录访问日志

    3、  记录数据变化记录

    4、  执行步骤跟踪和计时

    5、  异常日志

    6、  权限判断

    步骤:

    1、  数据库设计、建表这类的直接略过,假设有了一张表,我们要往这个表里面添加数据

    2、  根据要添加的字段,设置一个json文件,对服务进行描述,并且给这个服务设置一个变化,作为区分。

    3、  客户端提交数据和服务变化。

    4、  服务器端,获取数据和服务变化,调用对应的程序进行处理。

    5、  处理完毕后处理返回给客户的信息

    6、  如果有特殊业务需求,可以用插件的方式来实现。

    7、  完成

    第一步,不管用什么方式做项目,都是要做的。

    第二步需要弄一个json文件,这个可以自动生成,不用手写

    第三步相当于做一个路由,路由规则制定好了就不用再写代码了。

    第四步由框架完成,不需要写代码

    第五步判断一下是否成功,按照规则给浏览器返回数据,也不用一遍一遍写。

    第六步不是必须的,大部分的增删改查都是不需要插件的。

    所以,基本上做一个json文件,就可以搞定一个服务。需要写的代码无限接近零代码。而json文件又可以自动生成。

    下面是json文件的例子:(这个可以自动生成)

    {
      "operationMode":"add",
      "pluginBefore":"",
      "pluginAfter":"",
      "tableInfo":{
        "tableName": "node_user",
        "primaryKey":"id",
        "sql": "INSERT INTO node_user(id,name,age) VALUES(0,?,?)" ,
        "sqlSelect": "SELECT * FROM node_user WHERE id = ?" ,
        "column":["name","age"]
    
      } 
    
    }

    然后再说一下代码类型,可以分为两类——框架类和项目类

    像.net框架、ado.net、express这类,内部的实现代码都是属于框架级的,内部有再多的代码,也不应该算到项目里面。

    而调用类库、使用框架实现项目的代码,才是项目级的代码,才算作代码量。

    这个要先说清楚,然后再发后面的代码。

    http的使用,属于项目级的,http的内部实现,就是框架级的。

    同理,添加服务的调用部分属于项目级的,服务内部的实现代码属于框架级的。

    先不上http了,写一个简单的测试用代码,优点是不用打开浏览器就可以进行测试。要不然每次都要打开浏览器,太麻烦了。

    这个不是正式的代码,仅仅是初期测试用的。这个是项目级别的代码。

    /**
     * Created by jyk00 on 2019/3/31.
     * curd的服务
     */
    
    //测试添加服务
    
    //精确计时
    var time = require('../preciseTime').time;
    //创建添加服务对象
    var service = require('./serviceAdd');
    
    var trace={
        title:'收到一个请求:100',
        msg:'',
        startTime:time(),
        endTime:0,
        useTime:0,
        items:[]
    };
    
    service.start(100,trace,function (err,info) {
    
        msg.endTime = time();
        msg.useTime = time() - msg.startTime;
    
        console.log('完成服务:'+JSON.stringify(trace));
    
    });

    添加服务的代码(业务层) 框架级代码

    /**
     * Created by jyk00 on 2019/3/31.
     * 添加数据的服务
     */
    
    
    exports.start = function(code,trace,callback) {
        //精确计时
        var time = require('../preciseTime').time;
    
        var traceAdd = {
            title:'开始添加数据的服务',
            msg:'',
            startTime:time(),
            endTime:0,
            useTime:0,
            items:[]
        };
    
        trace.items.push(traceAdd);
    
        /** 根据配置信息实现添加数据的功能
         * 获取服务信息
         * 接收数据
         * 验证数据
         * 调用插件
         * 持久化
         * 获取持久化后数据
         * 写数据变化日志
         * 返回结果
         */
    
        //获取服务信息
        //console.log('服务ID:' + code);
        var meta = require('./service_'+ code +'.json');
        console.log('获取服务信息:' + meta);
    
        //获取实体类,先模拟一下
        var data = require('./node_user.json');
    
        var info={
            trace:traceAdd,
            requestId:0,
            serviceId:code,
            data:data,
            table:meta.tableInfo
        };
    
        //验证数据,暂时略
    
        //调用持久化前的插件
        var plugName = meta.pluginBefore;
        if (plugName.length === 0){
            //没有插件,不调用
            console.log('没有插件,不调用');
            //持久化及后续
            saveAndLast(data);
        }
        else
        {
            //有插件
            console.log('有插件,调用');
            var plug = require('../plugin/' + plugName);
            plug.begin(data,function(data){
                //持久化及后续
                saveAndLast(data);
            });
    
        }
    
        //持久化以及之后的事情
        function saveAndLast(data) {
            //持久化之添加数据
            var db = require('./dataBaseAdd');
    
            //持久化
            db.query(info,function(err, result){
                console.log('saveData的回调:' );
                console.log('result:',result);
    
                //调用持久化之后的插件
                plugName = meta.pluginAfter;
                if (plugName.length === 0){
                    //没有插件,不调用
    
                }
                else{
                    //有插件
                    plug = require('../plugin/' + plugName);
                    plug.begin(err, result,data,function() {
    
    
                    });
                }
    
            });
    
    
        }
    
    
    
    };

    持久化的代码(数据层) 框架级代码

    /**
     * Created by jyk00 on 2019/4/1.
     * 数据服务之添加操作
     
     */
    //持久化内部的跟踪
    var traceStartAddData = {};
    //捕捉异常
    process.on('uncaughtException', function (err)  {
        console.log('uncaughtException的trace:' +JSON.stringify(traceStartAddData));
        console.log("捕捉到异常啦");
        console.log(err);
    
    });
    
    exports.query = function(info,callback) {
        //精确计时
        var time = require('../preciseTime').time;
    
        //持久化之添加数据
        traceStartAddData = {
            title:'持久化之添加数据',
            msg:'',
            startTime:time(),
            endTime:0,
            useTime:0,
            items:[]
        };
    
        info.trace.items.push(traceStartAddData);
    
        /** 根据配置信息实现添加数据的功能
         * 获取表信息
         * 接收传入的数据,验证任务由上层搞定
         * 持久化
         * 获取持久化后数据
         * 写数据变化日志
         * 返回结果
         */
    
        //==================获取表信息和数据=================================
        var traceGetInfo = {
            title:'获取表信息和数据、定义dataChange',
            msg:'',
            startTime:time(),
            endTime:0,
            useTime:0,
            items:[]
        };
    
        traceStartAddData.items.push(traceGetInfo);
    
        //获取表信息
        var tableInfo = info.table;
        //获取实体类
        var data = info.data;
    
        //记录数据变化情况
        var dataChange = {
            requestId:info.requestId,
            serviceId:info.serviceId,
            tableID:info.table.tableId,
            dataID:0,
            oldDataJson:'',
            newDataJson:'',
            submitDataJson:JSON.stringify(info.data),
            dbResult:'',
            trace:JSON.stringify(info.trace),
            addUserid:1
        };
        traceGetInfo.endTime = time();
        traceGetInfo.useTime = time() - traceGetInfo.startTime;
    
        //==================创建MySql对象=================================
        var traceCreateMySql = {
            title:'创建MySql对象、cnString、connection',
            msg:'',
            startTime:time(),
            endTime:0,
            useTime:0,
            items:[]
        };
        traceStartAddData.items.push(traceCreateMySql);
    
        //创建mysql对象
        var mysql  = require('mysql');
        var cnString = require('../sqlConnection.json');
        var connection = mysql.createConnection(cnString);
    
        traceCreateMySql.endTime = time();
        traceCreateMySql.useTime = time() - traceCreateMySql.startTime;
    
        //==================发送持久化请求=================================
        var traceAddNewData = {
            title:'准备发送持久化请求,添加一条数据',
            msg:'',
            startTime:time(),
            endTime:0,
            useTime:0,
            items:[]
        };
    
        traceStartAddData.items.push(traceAddNewData);
    
        var sql = tableInfo.sql;
        //数据转换成数组
        var valuesParams = createParams(tableInfo,data);
    
        myQuery(sql,valuesParams,traceAddNewData,function (err, result) {
            //数据添加完成后的回调
            //console.log('持久化的回调的trace:' +JSON.stringify(traceStartAddData));
    
            if(err){
                console.log('[INSERT ERROR ] - ',err.message);
                traceAddNewData.msg += '_err:' + JSON.stringify(err);
                callback(err, result);
                return;
            }
    
            //记录数据变化记录,
            var log = require('./serviceAdd_11.json');
            //记录添加数据后的返回信息
            dataChange.dbResult = JSON.stringify(result);
          
            //从数据库里获取刚添加的数据
            var traceGetNewData = {
                title:'获取数据库里添加完成的数据',
                msg:'',
                startTime:time(),
                endTime:0,
                useTime:0,
                items:[]
            };
            traceAddNewData.items.push(traceGetNewData);
    
            myQuery(tableInfo.sqlSelect,[result.insertId],traceGetNewData,function (err, result) {
                //获取一条记录完毕
                //console.log('获取更新数据的回调result:' +JSON.stringify(result));
                //console.log('获取更新数据的回调的trace:' +JSON.stringify(traceStartAddData));
    
                //记录数据变化日志
                var traceAddlog = {
                    title:'记录数据变化日志',
                    msg:'',
                    startTime:time(),
                    endTime:0,
                    useTime:0,
                    items:[]
                };
                traceGetNewData.items.push(traceAddlog);
    
                //数据库里的新数据
                dataChange.newDataJson = JSON.stringify(result);
                //目前为止的跟踪记录
                dataChange.trace = JSON.stringify(info.trace);
                valuesParams = createParams(log.tableInfo,dataChange);
    
               //提交操作
                myQuery(log.tableInfo.sql,valuesParams,traceAddlog,function (err, result){
                    //数据变化日志回调完毕
                    console.log('数据变化日志回调完毕:' +JSON.stringify(info.trace));
    
                });
    
            });
            connection.end();
    
            //回调,不等数据变化的日志了
            callback(err, result);
    
        });
    
        //console.log('调用结束等待结果');
    
        //封装数据库操作,以及计时器
        function myQuery(sql,vParme,traces,callback) {
            //console.log('myQuery的sql:' +sql);
            traces.msg += 'sql:'+sql;
            traces.msg += '_values:' + valuesParams;
    
            var conn = mysql.createConnection(cnString);
            conn.connect();
            conn.query(sql,vParme,function (err, result) {
                //console.log('myQuery的回调:' +err);
    
                traceStart.endTime = time();
                traceStart.useTime = time() - traceStart.startTime;
    
                if(err){
                    console.log('[ERROR ] - ',err.message);
                    traceStart.title += '——执行出错:'+ err.message;
                    traceStart.error = JSON.stringify(err)
                    callback(err, result);
                    return;
                }
                traceStart.title += '——成功!';
    
                callback(err, result);
    
            });
            conn.end();
            //请求发送完毕
            //console.log('请求发送完毕:');
    
            traces.endTime = time();
            traces.useTime = time() - traces.startTime;
    
            //记录完成开始时间
            var traceStart = {
                title:'请求发送完毕,等待反馈',
                startTime:time(),
                endTime:0,
                useTime:0,
                items:[]
            };
    
            traces.items.push(traceStart);
        }
    
        //拼接valuesParams
        function createParams(colInfo,data){
            //console.log('开始拼接数据数组');
            var valuesParams = [];
            //数据变成数组的形式
            var colName = "";
            for (var i=0 ;i<colInfo.column.length;i++) {
                colName = colInfo.column[i];
                valuesParams.push(data[colName]);
            }
           
            return valuesParams;
    
        }
    
        //拼接sql
        function createSql2(){
         
            sql = 'INSERT INTO ' +meta.tableName ;
    
            var cols = "(" + meta.primaryKey;
            var values = " VALUES(0";
            var valuesParams = [];
    
            //拼接字段名和参数
            for (var key in meta.cols) {
                cols += ',' + key;
                values += ',?';
                valuesParams.push(meta.cols[key]);
            }
            sql +=cols + ')' + values + ')';
            console.log(sql);
    
        }
    
    };

    跟踪记录

    {
        "title": "开始添加数据的服务",
        "msg": "",
        "startTime": 2950080457.323715,
        "endTime": 0,
        "useTime": 0,
        "items": [{
            "title": "持久化之添加数据",
            "msg": "",
            "startTime": 2950080463.596571,
            "endTime": 0,
            "useTime": 0,
            "items": [{
                "title": "获取表信息和数据、定义dataChange",
                "msg": "",
                "startTime": 2950080463.608944,
                "endTime": 2950080463.683611,
                "useTime": 0.08490705490112305,
                "items": []
            }, {
                "title": "创建MySql对象、cnString、connection",
                "msg": "",
                "startTime": 2950080463.702811,
                "endTime": 2950080586.696783,
                "useTime": 122.99781227111816,
                "items": []
            }, {
                "title": "准备发送持久化请求,添加一条数据",
                "msg": "sql:INSERT INTO node_user(id,name,age) VALUES(0,?,?)_values:王五,45",
                "startTime": 2950080586.707023,
                "endTime": 2950080592.260519,
                "useTime": 5.556482791900635,
                "items": [{
                    "title": "请求发送完毕,等待反馈——成功!",
                    "startTime": 2950080592.271186,
                    "endTime": 2950080612.196954,
                    "useTime": 19.944968223571777,
                    "items": []
                }, {
                    "title": "获取数据库里添加完成的数据",
                    "msg": "sql:SELECT * FROM node_user WHERE id = ?_values:王五,45",
                    "startTime": 2950080615.264262,
                    "endTime": 2950080616.479836,
                    "useTime": 1.218986988067627,
                    "items": [{
                        "title": "请求发送完毕,等待反馈——成功!",
                        "startTime": 2950080616.488796,
                        "endTime": 2950080624.55792,
                        "useTime": 8.072536945343018,
                        "items": []
                    }, {
                        "title": "记录数据变化日志",
                        "msg": "",
                        "startTime": 2950080625.123253,
                        "endTime": 0,
                        "useTime": 0,
                        "items": []
                    }]
                }]
            }]
        }]
    }

    我们在写项目的时候,最郁闷的就是,运行的时候报错了,但是又不知道是哪一行出错了。如果某个函数被调用好几次,那么就更头疼了,到底是哪一次的调用出错了呢?

    有了这个跟踪就能够很方便的知道到底是执行到了哪里出的错误,便于定位和修改。

    ps:

    这几天写代码的感受就是——糟糕透了。怪不得node都这么多年了还没火。真的太难驾驭了。

  • 相关阅读:
    IP保留地址
    HTML5读取本地文件
    angularjs中动态为audio绑定src
    canvas移动端常用技巧图片loading
    angularjs三级联动
    angular实现select的ng-options
    ng-bind-html在ng-repeat中问题的解决办法
    JS判断是否在微信浏览器打开
    angular实现select的ng-options
    创建 AngularJS 自定义过滤器,带自定义参数
  • 原文地址:https://www.cnblogs.com/jyk/p/10673617.html
Copyright © 2011-2022 走看看