用node.js实现ORM的一种思路

 

  ORM是O和R的映射。O代表面向对象,R代表关系型数据库。二者有相似之处同时也各有特色。就是因为这种即是又非的情况,才需要做映射的。

  理想情况是,根据关系型数据库(含业务需求)的特点来设计数据库。同时根据面向对象(含业务需求)的特点来设计模型(实体类)。然后再去考虑如何做映射。但是理想很骨jian感dan,现实太丰fu满za。

  没见哪个ORM是这么做的,也没见哪位高手会这么做设计。那么实际情况是什么样子的呢?以.net的Entity Framework为例。

  DB frist,就是先设计好数据库,然后根据库里的表、主外键等自动创建实体类。然后可以通过LinQToSQL来操作。这样创建出来的实体类显然缺乏面对对象的特色。

  Code frist,就是先设计实体类,然后根据实体类和特性来自动创建表和主外键、约束等。而为了严谨,定义实体类的时候需要说明一下主外键等具有关系型特色的东东。

如下图

 

 

  现在想用node来做一套引擎。刚刚接触node,估计会有现成的orm吧,不知道他们是怎么做的,先不管他们了,先把自己的思路弄清楚再说,恩恩。

  为啥要选择node呢?以为他原生支持json。Json在前端那是主场,js原生支持json,各种操作都非常流畅舒服。但是json到了后端(C#)就麻烦了,C#原生不支持json,只能作为字符串,或者实体类序列化的形态。这就需要转来转去的,很是麻烦。

  而采用node那么后端也可以用js来编码,也就是说会原生支持json。这就舒服多了。想想,前端创建json(实体类),然后整个提交给后端,后端接到json直接进行处理(安全验证、业务处理),然后直接持久化。是不是很爽!

 

  采用node还有一个好处,那就是他可以在运行时定义实体类的属性,比如增加属性。这个在C#里是无法实现的。

  为啥一定要运行时可以修改实体类?因为这样做可以避免实体类数量爆炸。

 

  打开你的项目,数一数定义了多少的实体类?是不是项目越大实体类就越多?当需要发生变化,需要给实体类增加一个属性的时候,是不是需要各种改代码?虽然VS可以帮我们做很多工作。

 

  所以说还是在运行时可以随意修改实体类的好,这样可以极大地避免修改代码的问题。(因为根本就没有啥代码)

 

  这一篇主要是说思路,所以先简单设计一个json来表示一下。

  设计这个json的目的是,引擎可以根据json的情况来拼接成SQL,然后交给数据库处理。

 

{
  "operationMode":"add",// add\update\delete\select
  "tableCount":1, //支持多表的级联添加、修改
  "fieldInfo":[{//主表的字段,参与操作的字段,不参与的不用写。第一个字段是主键(不支持多主键)
    "tableName": "t1", //表名。
    "primaryKey":"id",//主键字段名。我不想把主键字段名限制为必须是“ID”
    "_sqlCache": "" ,//缓存的sql语句,每次都拼接sql也挺烦的,弄个缓存存放拼接好的sql。
    "fieldList":{      //涉及到的字段,并不需要把表里的字段都放进来,根据业务需求设计
                       //客户端提交的json与之对应
      "field1Name":"field1Value",
      "field2Name":"field2Value"
    }
  },
  { //从表的字段,可以不设置
    "primaryKey": "id", //主键字段名。我不想把主键字段名限制为必须是“ID”
    "foreignKey": "foreignKeyid", //主键字段名。我不想把主键字段名限制为必须是“ID”
    "_sqlCache": "", //缓存的sql语句,每次都拼接sql也挺烦的,弄个缓存存放拼接好的sql。
    "fieldList": {   //涉及到的字段(不含外键字段),并不需要把表里的字段都放进来,根据业务需求设计
                     //客户端提交的json与之对应
      "field1Name": "field1Value",
      "field2Name": "field2Value"
    }
  }  //  从表的字段,参与操作的字段,不参与的不用写。第一个字段是主键,第二个字段是外键
  ],

  "findCol":[{
    "colName":"col1",
    "key1":"abc",
    "key2":"abc", //范围查询时使用,比如从几号到几号
    "findKind":" {colName} like {key}" //查询方式:like、not Like、in、=、between等
  }]

}

 

  一般的ORM是以实体类为核心,要求实体类的完整,就说一个实体类要和一个完整的表做映射。比如要下架一个商品,一般的做法是先把这个商品从数据库里读取出来实例化之后,修改标记属性(字段),然后再把整个实体类持久化(保存到数据库)。

  但是SQL怎么写呢?一个update就可以了,不用读取数据的,这样效率就有点损耗。

  那么如果要把一个分类的商品都下架呢?要把这个分类里的商品都折腾出来,然后批量改属性值,在批量持久化。

  如果写SQL语句呢?还是那一句SQL,只不过是把查询条件换一下,还是不需要折腾数据。这种情况下效率的差别就很大了。

  而我的这个思路呢,并不是以面向对象为核心的,而是以关系型数据库为核心。

  就是说不会把实体类和表做整体的映射,而是会把属性和字段做映射。就是说把一个表里的部分字段拿出来,做成一个实体类,然后进行操作。比如下架商品的例子

表:商品表

字段:isxiajia = 1

条件:id=1(单商品下架)  cate=2 (按照分类下架)

然后生成update语句就可以了。

  这是一个独立的“实体类”,这个类里面并不需要商品的其他属性,因为只是下架操作。另外查询条件也完全放开,不是仅仅依据ID查询,还可以按照其他字段来查询,比如分类字段。这样效率就可以得到提升。

  先开个头,还有后续。。。

 

时间: 2024-10-01 23:33:23

用node.js实现ORM的一种思路的相关文章

Sequelize 4.0.0(final) 发布,Node.js 的 ORM

Sequelize 4.0.0 发布了,Sequelize.js 提供对 MySQL,MariaDB,SQLite 和PostgreSQL 数据库的简单访问,通过映射数据库条目到对象,或者对象到数据库条目.简而言之,就是 ORM(Object-Relational-Mapper).Sequelize.js 完全是使用 JavaScript 编写,适用于 Node.js 的环境. v4 版本包含大量 bug 修复和更新,部分内容如下: [ADDED] Add isSoftDeleted helpe

Node.js编写组件的三种实现方式_node.js

首先介绍使用v8 API跟使用swig框架的不同: (1)v8 API方式为官方提供的原生方法,功能强大而完善,缺点是需要熟悉v8 API,编写起来比较麻烦,是js强相关的,不容易支持其它脚本语言. (2)swig为第三方支持,一个强大的组件开发工具,支持为python.lua.js等多种常见脚本语言生成C++组件包装代码,swig使用者只需要编写C++代码和swig配置文件即可开发各种脚本语言的C++组件,不需要了解各种脚本语言的组件开发框架,缺点是不支持javascript的回调,文档和de

三种Node.js写文件的方式_node.js

本文分享了Node.js写文件的三种方式,具体内容和如下 1.通过管道流写文件 采用管道传输二进制流,可以实现自动管理流,可写流不必当心可读流流的过快而崩溃,适合大小文件传输(推荐) var readStream = fs.createReadStream(decodeURIComponent(root + filepath.pathname)); // 必须解码url readStream.pipe(res); // 管道传输 res.writeHead(200,{ 'Content-Type

Node.js进程管理之子进程

一.理论 这两天感情生活不顺利,想遇到对的人真的很难,可能因为各种条件无法让两人在一起,友谊的小船说翻就翻,对于在感情这块比较白痴的我真心烦.可能也就只有博客能打发我的业余时间.之前看多进程这一章节时发现这块东西挺多,写Process模块的时候也有提到,今天下午午休醒来静下心来好好的看了一遍,发现也不是太难理解. Node.js是单线程的,对于现在普遍是多处理器的机器是一种浪费,怎么能利用起来呢?于是child_process模块出现了.child_process模块可以在其他进程上产生.派生,

Node.js重新刷新session过期时间的方法_node.js

在Node.js中,我们通常使用express-session这个包来使用和管理session,保存服务端和客户端浏览器之间的会话状态.那如何才能实现当用户刷新当前页面或者点击页面上的按钮时重新刷新session的过期时间呢?类似于ASP.NET中session会话状态,只要在一定的时间内页面一直保持活动状态,session就不会过期.通过下面的代码可以实现这个功能,我们在Node.js的代码中加入下面的中间件: // use this middleware to reset cookie ex

node.js入门教程迷你书、node.js入门web应用开发完全示例_基础知识

本书状态 你正在阅读的已经是本书的最终版.因此,只有当进行错误更正以及针对新版本Node.js的改动进行对应的修正时,才会进行更新. 本书中的代码案例都在Node.js 0.6.11版本中测试过,可以正确工作. 读者对象 本书最适合与我有相似技术背景的读者: 至少对一门诸如Ruby.Python.PHP或者Java这样面向对象的语言有一定的经验:对JavaScript处于初学阶段,并且完全是一个Node.js的新手. 这里指的适合对其他编程语言有一定经验的开发者,意思是说,本书不会对诸如数据类型

mac下Node.js+express搭建web应用实例

mac用户可以有三种方式 一:brew方式 brew install node 二:手工编译的方式 1. 安装Xcode 2. 安装git 3 .运行下面的命令行编译node.js git clone git://github.com/joyent/node.git cd node ./configure make sudo make install 三:从官网下载pkg包安装 http://nodejs.org/#download 强力推荐这种安装方式啊,因为上面两种我都尝试了失败的滋味 安装

不错的node.js入门

关于 本书致力于教会你如何用Node.js来开发应用,过程中会传授你所有所需的"高级"JavaScript知识.本书绝不是一本"Hello World"的教程. 状态 你正在阅读的已经是本书的最终版.因此,只有当进行错误更正以及针对新版本Node.js的改动进行对应的修正时,才会进行更新. 本书中的代码案例都在Node.js 0.6.11版本中测试过,可以正确工作. 读者对象 本书最适合与我有相似技术背景的读者: 至少对一门诸如Ruby.Python.PHP或者Ja

网络优化NginX和Node.js有几种办法?

译者:AlfredCheung 在搭建高吞吐量web应用这个议题上,NginX和Node.js可谓是天生一对.他们都是基于事件驱动模型而设计,可以轻易突破Apache等传统web服务器的C10K瓶颈.预设的配置已经可以获得很高的并发,不过,要是大家想在廉价硬件上做到每秒数千以上的请求,还是有一些工作要做的. 这篇文章假定读者们使用NginX的HttpProxyModule来为上游的node.js服务器充当反向代理.我们将介绍Ubuntu 10.04以上系统sysctl的调优,以及node.js应