使用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查询,还可以按照其他字段来查询,比如分类字段。这样效率就可以得到提升。

总结

以上所述是小编给大家介绍的使用Node.js实现ORM的一种思路详解,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我们网站的支持!

(0)

相关推荐

  • node.js中的url.format方法使用说明

    方法说明: 将一个解析后的URL对象.转成.一个格式化的URL字符串. 语法: 复制代码 代码如下: url.format(urlObj) 接收参数: urlObj 表示 URL对象,可包含以下属性:(可对照例子) href                      完整路径 protocolis            协议(如http://) auth hostname            主机名 port                      端口 host              

  • node.js中的path.normalize方法使用说明

    方法说明: 输出规范格式的path字符串. 语法: 复制代码 代码如下: path.normalize(p) 由于该方法属于path模块,使用前需要引入path模块(var path= require("path") ) 例子: 复制代码 代码如下: path.normalize('/foo/bar//baz/asdf/quux/..') // returns '/foo/bar/baz/asdf' 源码: 复制代码 代码如下: // windows version   exports

  • 浅谈Node.js ORM框架Sequlize之表间关系

    Sequelize模型之间存在关联关系,这些关系代表了数据库中对应表之间的主/外键关系.基于模型关系可以实现关联表之间的连接查询.更新.删除等操作.本文将通过一个示例,介绍模型的定义,创建模型关联关系,模型与关联关系同步数据库,及关系模型的增.删.改.查操作. 数据库中的表之间存在一定的关联关系,表之间的关系基于主/外键进行关联.创建约束等.关系表中的数据分为1对1(1:1).1对多(1:M).多对多(N:M)三种关联关系. 在Sequelize中建立关联关系,通过调用模型(源模型)的belon

  • Node.js使用orm2进行update操作时关联字段无法修改的解决方法

    前言 最近在工作中遇到一个问题,在使用Orm2进行model修改时,发现当对关联字段进行update操作时,执行了2次SQL,第一次把值改为了我们期望的值,第二次又会把值改回成原来的值. 经过调查,当autoFetch开启时,会自动取得关联model,此时的model为: { roomId: xxx, // 关联的roomId room: { // 关联的room对象 } } 第一次会按照roomId去修改,第二次则会按照fetch的关联对象room进行修改,导致了我们看到的执行了两次SQL的情

  • 使用Node.js实现ORM的一种思路详解(图文)

    ORM是O和R的映射.O代表面向对象,R代表关系型数据库.二者有相似之处同时也各有特色.就是因为这种即是又非的情况,才需要做映射的. 理想情况是,根据关系型数据库(含业务需求)的特点来设计数据库.同时根据面向对象(含业务需求)的特点来设计模型(实体类).然后再去考虑如何做映射.但是理想很骨jian感dan,现实太丰fu满za. 没见哪个ORM是这么做的,也没见哪位高手会这么做设计.那么实际情况是什么样子的呢?以.net的Entity Framework为例. DB frist,就是先设计好数据库

  • Node.js中参数传递的两种方式详解

    目录 参数传递方式 GET方式 POST方式 动态网页 参数传递方式 在Node.js中,参数传递常见的共两种方式: GET方式:通过地址栏键=值的方式进行传递. POST方式:通过表单的方式传递请求数据. GET方式 GET方式通常是在请求地址中以[?参数1=值1&参数2=值2]的格式进行传递,在Node.js中可以通过获取url然后进行获取参数,如下所示: //1.引入http模块 var http = require('http'); //2.创建服务 var server = http.

  • node.js中grunt和gulp的区别详解

    node.js中grunt和gulp的区别详解 自nodeJS登上前端舞台,自动化构建变得越来越流行.目前最流行的当属grunt和gulp,这两个光看名字挺像,功能也差不多,不过gulp能在grunt这位大哥如日中天的境况下开辟出自己的一片天地,有着她独到的优点. 易用 Gulp相比Grunt更简洁,而且遵循代码优于配置策略,维护Gulp更像是写代码. 高效 Gulp相比Grunt更有设计感,核心设计基于Unix流的概念,通过管道连接,不需要写中间文件. 高质量 Gulp的每个插件只完成一个功能

  • 对node.js中render和send的用法详解

    大多数情况下,渲染内容用res.render(),将会根据views中的模板文件进行渲染.如果不想使用views文件夹,想自己设置文件夹名字,那么app.set("views","aaaa"); 如果想写一个快速测试页,当然可以使用res.send().这个函数将根据内容,自动帮我们设置了Content-Type头部和200状态码.send()只能用一次,和end一样.和end不一样在哪里?能够自动设置MIME类型. 如果想使用不同的状态码,可以: res.stat

  • Node.js中Express框架的使用教程详解

    目录 Express简介 Express生成器 1. 什么是Express生成器 2. 安装Express生成器 创建Express项目 安装项目依赖 运行Express项目 Express目录结构说明 创建一个新路由模块 1. 创建ejs模块文件 2. 创建路由文件 3. 在app.js中引入路由 4. 运行项目 经过前面几天对Node.js的学习,基本的开发知识已经逐渐掌握,所谓工欲善其事必先利其器,今天进一步学习Node.js的开发框架Express.利用Express框架可以快速的进行W

  • 原生js实现拖拽功能基本思路详解

    如果要设置物体拖拽,那么必须使用三个事件,并且这三个事件的使用顺序不能颠倒. 1.onmousedown:鼠标按下事件 2.onmousemove:鼠标移动事件 3.onmouseup:鼠标抬起事件 拖拽的基本原理就是根据鼠标的移动来移动被拖拽的元素.鼠标的移动也就是x.y坐标的变化;元素的移动就是style.position的 top和left的改变.当然,并不是任何时候移动鼠标都要造成元素的移动,而应该判断鼠标左键的状态是否为按下状态,是否是在可拖拽的元素上按下的. 基本思路如下: 拖拽状态

  • Node.js编程中客户端Session的使用详解

    静态网站很容易扩展.你只需要全部缓存,不需要考虑从不同服务器组合有状态的内容给用户. 可惜,大多数Web应用使用有状态的内容提供个性化体验.如果你的应用可以登录,就需要记住用户的Session.经典的处理方法是客户端设置包含随机唯一Session标识的Cookie,被标识的Session数据保存到服务端. 扩展有状态服务 当扩展服务的时候,你肯定有三种选择: 不同服务端同步Session数据 不同服务端连接单点中心(获取Session) 保证用户访问同一个服务端 但都有缺陷: 同步数据增加性能开

  • node.js中Util模块作用教程示例详解

    目录 从类型判断说起 严格相等 Error First & Promise 调试与输出 从类型判断说起 在 JavaScript 中,进行变量的类型校验是一个非常令人头疼的事,如果只是简单的使用 typeof 会到各种各样的问题. 举几个简单的: console.log(typeof null) // 'object' console.log(typeof new Array) // 'object' console.log(typeof new String) // 'object' 后来,大

  • Node.js中HTTP模块与事件模块详解

    Node.js的http服务器 通过使用HTTP模块的低级API,Node.js允许我们创建服务器和客户端.刚开始学node的时候,我们都会遇到如下代码: 复制代码 代码如下: var http = require('http'); http.createServer(function (req,res) {     res.end('Hello World\n'); }).listen(3000,"127.0.0.1"); console.log("Server funni

  • Node.js学习之查询字符串解析querystring详解

    前言 查询字符串模块提供了解析和格式化工具URL查询字符串的API,本文将详细介绍关于Node.js查询字符串解析querystring的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. 一.querystring.parse(str[, sep[, eq[, options]]]) 这个API将URL查询字符串解析为键和值的集合 str:URL查询字符串 sep:标明字符串中用于划分键值对的符号,默认为"&" eq:用以标明查询字符串中键和值之间的符

随机推荐