基于nodejs的流水线式的CRUD服务。依赖注入可以支持插件。
写代码好多年了,发现大家的思路都是写代码、写代码、写代码,还弄了个称号——码农。
我是挺无语的,我的思路是——不写代码、不写代码、不写代码!
无聊的代码为啥要重复写呢?甚至一写写好几年。
举个例子吧,要不然大家肯定很懵。
当我们刚开始学习数据库编程的时候,我们会先写一段代码,实现往一个表里添加数据的功能。这段代码是必须写的,不写怎么会?
然后熟悉这段代码,尽量知道其含义,越深入越好。
然后呢,进入项目组,发现项目里面有n张数据表,每个表都至少要有一个添加数据的功能。
那么怎么办?当然要写代码了。于是添加数据的代码被一遍又一遍的写,区别在于表名和字段名的不同,因为每个表都有自己的名称和自己的字段。
仅仅是因为表名和字段名的不同,就要一遍一遍的写类似的代码吗?这就是我说的无聊的代码。
虽然各位前辈想了很多很多的方法,比如代码生成器,这样类似的代码就不用写了,直接生成就好。但是当字段名变了怎么办?增加了一个字段怎么办?
比如orm,比如各种框架,但是总是要写代码。没发现谁把不写代码作为目标。
我在这些年里也在不断尝试,虽然有了一些效果,但是缺点还是很多,离不写代码还很远,只是做到了不写重复代码的目的。
我一直用c#来实现我的想法,但是c#太严谨了,好多思路实现起来太复杂。比如:
1、 必须先定义实体类,然后才能各种传递
2、 “插件”实现起来非常不方便。
3、 必须先编译,然后才能加载。
4、 对json不太友好,需要反复转换。
5、 反射、泛型这类的不太理想。
看了一下其他语言,发现Node非常适合我的想法,也能避免上面的那些“缺点”,只是由于种种原因,现在才开始正式学习。
Node使用的是JavaScript,天生对json非常友好,可以直接操作,不用各种转换。
可以用require加载JavaScript代码并且立即编译,可以利用这个特性方便的写插件。
require也可以加载json文件,这样依赖注入就很容易实现了。
性能方面也不用担心,毕竟阿里爸爸都在用。
好吧,介绍一下思路,上流程图
这是初步想法,具体细节还在不断完善。
下面是第一版代码,很初级,只是实现基本功能,因为这是我第一次写node,边熟悉node的写法和基本功能,边实现我的想法。
话说,语言里面没有node呢,只好选择JavaScript了。
/**
* Created by jyk00 on 2019/3/31.
* 添加数据的服务
*/ exports.start = function(code) {
console.log('开始添加数据'); /** 根据配置信息实现添加数据的功能
* 获取服务信息
* 接收数据
* 验证数据
* 调用插件
* 持久化
* 获取持久化后数据
* 写数据变化日志
* 返回结果
*/ //获取服务信息
console.log('服务ID:' + code);
var meta = require('./serviceAdd_'+ code +'.json');
console.log('获取服务信息:' + meta); //获取实体类,先模拟一下
var data = require('./node_user.json'); //验证数据,暂时略 //调用持久化前的插件 //持久化
saveData(function(err, result) {
console.log('#######################');
console.log('saveData的回调');
console.log('result:', result); }); //调用持久化之后的插件 //记录数据变化日志 //持久化数据
function saveData(callback) {
console.log('开始持久化');
//创建mysql对象
var mysql = require('mysql');
var cnString = require('../sqlConnection.json');
var connection = mysql.createConnection(cnString); var sql = meta.sqlCache;
//拼接数据
var valuesParams = createParams(); connection.connect();
connection.query(sql,valuesParams,function (err, result) {
if(err){
console.log('[INSERT ERROR ] - ',err.message);
callback(err, result);
return;
}
console.log('-------INSERT by service ----------');
console.log('INSERT ID:',result.insertId);
console.log('#######################'); callback(err, result); }); connection.end();
console.log('调用结束等待结果'); } //拼接valuesParams
function createParams(){
console.log('开始拼接数据数组'); var params = [];
//数据变成数组的形式
var colName = "";
for (var i=0 ;i<meta.column.length;i++) {
colName = meta.column[i];
params.push(data[colName]);
} return params; } };
下面是第二版代码,功能多了一些,代码也更难看了,都是异步害的。这么丑陋的代码,肯定要进行改善的。
/**
* Created by jyk00 on 2019/3/31.
* 添加数据的服务
*/ exports.start = function(code) {
console.log('开始添加数据'); /** 根据配置信息实现添加数据的功能
* 获取服务信息
* 接收数据
* 验证数据
* 调用插件
* 持久化
* 获取持久化后数据
* 写数据变化日志
* 返回结果
*/ //获取服务信息
console.log('服务ID:' + code);
var meta = require('./serviceAdd_'+ code +'.json');
console.log('获取服务信息:' + meta); //获取实体类,先模拟一下
var data = require('./node_user.json'); //验证数据,暂时略 //调用持久化前的插件
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) {
//持久化
saveData(data,function(err, result){
console.log('#######################');
console.log('saveData的回调:' + data.age);
console.log('result:',result); //调用持久化之后的插件
plugName = meta.pluginAfter;
if (plugName.length === 0){
//没有插件,不调用 //记录数据变化日志
}
else{
//有插件
plug = require('../plugin/' + plugName);
plug.begin(err, result,data,function() { //记录数据变化日志
});
} }); } //持久化数据
function saveData(data,callback) {
console.log('开始持久化');
console.log('saveData的age:' + data.age);
//创建mysql对象
var mysql = require('mysql');
var cnString = require('../sqlConnection.json');
var connection = mysql.createConnection(cnString); var sql = meta.sqlCache;
console.log('sql:' + sql);
//拼接数据
var valuesParams = createParams(data); connection.connect();
connection.query(sql,valuesParams,function (err, result) {
if(err){
console.log('[INSERT ERROR ] - ',err.message);
callback(err, result);
return;
}
console.log('-------INSERT by service ----------');
console.log('INSERT ID:',result.insertId);
console.log('#######################'); callback(err, result); }); connection.end();
console.log('调用结束等待结果'); } //拼接valuesParams
function createParams(data){
console.log('开始拼接数据数组');
console.log('createParams的age:' + data.name);
var valuesParams = [];
//数据变成数组的形式
var colName = "";
for (var i=0 ;i<meta.column.length;i++) {
colName = meta.column[i];
valuesParams.push(data[colName]);
} return valuesParams; } };
今天先到这里,代码在不断改进中。以上代码都是可以正常运行的。
第二版的代码,有很多缺点,比如层次不分明,思路混乱,没法扩展。因为这还只是单表的添加,那么主从表的添加呢,批量添加又怎么办?还是要不断的改进的。
基于nodejs的流水线式的CRUD服务。依赖注入可以支持插件。的更多相关文章
- NodeBB,一个基于nodejs的响应式论坛
喜欢方便的同学请绕道去discuz,好吧我是nodejs的重视患者,首先你要有自己的vps或则云空间,比如9cloud,我今天用的是阿里云的VPS. 进入阿里云Ubuntu主机 .... 输入密码进入 ...
- 清晰架构(Clean Architecture)的Go微服务: 依赖注入(Dependency Injection)
在清晰架构(Clean Architecture)中,应用程序的每一层(用例,数据服务和域模型)仅依赖于其他层的接口而不是具体类型. 在运行时,程序容器¹负责创建具体类型并将它们注入到每个函数中,它使 ...
- (转)也谈基于NodeJS的全栈式开发(基于NodeJS的前后端分离)
原文链接:http://ued.taobao.org/blog/2014/04/full-stack-development-with-nodejs/ 随着不同终端(pad/mobile/pc)的兴起 ...
- 也谈基于NodeJS的全栈式开发(基于NodeJS的前后端分离)
前言 为了解决传统Web开发模式带来的各种问题,我们进行了许多尝试,但由于前/后端的物理鸿沟,尝试的方案都大同小异.痛定思痛,今天我们重新思考了“前后端”的定义,引入前端同学都熟悉的NodeJS,试图 ...
- 基于NodeJS的全栈式开发(基于NodeJS的前后端分离)
也谈基于NodeJS的全栈式开发(基于NodeJS的前后端分离) 前言 为了解决传统Web开发模式带来的各种问题,我们进行了许多尝试,但由于前/后端的物理鸿沟,尝试的方案都大同小异.痛定思痛,今天我们 ...
- 基于NodeJS进行前后端分离
1.什么是前后端分离 传统的SPA模式:所有用到的展现数据都是后端通过异步接口(AJAX/JSONP)的方式提供的,前端只管展现. 从某种意义上来说,SPA确实做到了前后端分离,但这种方式存在两个问题 ...
- 基于ABP模块组件与依赖注入组件的项目插件开发
注意,阅读本文,需要先阅读以下两篇文章,并且对依赖注入有一定的基础. 模块系统:http://www.cnblogs.com/mienreal/p/4537522.html 依赖注入:http://w ...
- typescript nodejs 依赖注入实现
依赖注入通常也是我们所说的ioc模式,今天分享的是用typescript语言实现的ioc模式,这边用到的主要组件是 reflect-metadata 这个组件可以获取或者设置元数据信息,它的作用是拿到 ...
- spring3——IOC之基于XML的依赖注入(DI )
我们知道spring容器的作用是负责对象的创建和对象间关系的维护,在上一篇博客中我们讲到spring容器会先调用对象的无参构造方法创建一个空值对象,那么接下来容器就会对对象的属性进行初始化,这个初始化 ...
随机推荐
- Linux命令及架构部署大全
1.Linux系统基础知识 Linux 基础优化配置 Linux系统根目录结构介绍 linux系统重要子目录介绍 Linux基础命令(之一)详解 Linux基础命令(之二)详解 Linux文件系统 L ...
- Android开发:UI相关(一)自定义样式资源
一.自定义样式资源: 1.在drawble中新建xml资源文件: 如果新建的xml文件没有自动放置在drawable文件夹下,就手动移动到drawable下. 2.编写样式代码: < ...
- 中国.NET:各地微软技术俱乐部汇总(更新中...)
与微软技术的发展历程相似,微软俱乐部的发展同样经历着沉沉浮浮.2002年周庆麒先生创办的著名Office技术论坛Excel Home的上线,各种线上技术社区在中国的互联网世界中萌发.接着以鞠海洋(广州 ...
- Tomcat 对 HTTP 协议的实现(上)
协议,直白的说就是存在一堆字节,按照协议指定的规则解析就能得出这堆字节的意义.HTTP 解析分为两个部分:解析请求头和请求体. 请求头解析的难点在于它没有固定长度的头部,也不像其他协议那样提供数据包长 ...
- [JavaScript] 函数节流(throttle)和函数防抖(debounce)
js 的函数节流(throttle)和函数防抖(debounce)概述 函数防抖(debounce) 一个事件频繁触发,但是我们不想让他触发的这么频繁,于是我们就设置一个定时器让这个事件在 xxx 秒 ...
- MySQL/MariaDB数据库忘掉密码解决办法--技术流ken
前言 有些时候我们常常会忘掉一些服务的密码,比如系统密码,我们可以进入救援模式进行修改密码,可参考我之前的博客<Centos7破解密码的两种方法--技术流ken>.但有些时候我们也会忘掉数 ...
- C#中public、private、protected等关键字说明
public 公有访问.不受任何限制.private 私有访问.只限于本类成员访问,子类,实例都不能访问.protected 保护访问.只限于本类和子类访问,实例不能访问.internal 内部访问. ...
- Vue + WebApi 小项目:构造自己的在线 Markdown 笔记本应用
Vue + WebApi 小项目:构造自己的在线 Markdown 笔记本应用 目录 概要 知识点 完整示例图 代码与资源文件 流程步骤 概要 基于 MVP 最小可行性产品设计理念,我们先完成一个可以 ...
- asp.net mvc前台显示带htm标签的解决办法(Razor —@Html.Raw())
数据是从后台富文本编辑后丢在数据库后取出的,不加Html.Raw(),前台就会把Html标签一同显示
- Java开发环境的搭建01——Eclipse篇(Windows)
搭建环境是换项目组和新入职的开发入项都必须面临的一件事情,搭搭环境,一天就过去了...本着不浪费生命不做重复的无用功,在这里写写环境搭建的基本功,这篇是介绍Java环境搭建,常见的开发IDE无非就两种 ...