node.js学习笔记(28) node-orm进阶三

也许你想监听Model实例的创建、修改、获取或者删除,那么正好node-rom为Model定义了一系列事件。

  • afterLoad : (no parameters) Right after loading and preparing an instance to be used;
  • afterAutoFetch : (no parameters) Right after auto-fetching associations (if any), it will trigger regardless of having associations or not;
  • beforeSave : (no parameters) Right before trying to save;
  • afterSave : (bool success) Right after saving;
  • beforeCreate : (no parameters) Right before trying to save a new instance (prior to beforeSave);
  • afterCreate : (bool success) Right after saving a new instance;
  • beforeRemove : (no parameters) Right before trying to remove an instance;
  • afterRemove : (bool success) Right after removing an instance;
  • beforeValidation : (no parameters) Before all validations and prior to beforeCreate and beforeSave;

Node-orm将这些events定义为hook,钩子。

钩子实际上是一个处理消息的程序段,通过系统调用,把它挂入系统。每当特定的消息发出,在没有到达目的窗口前,钩子程序就先捕获该消息,亦即钩子函数先得到控制权。这时钩子函数即可以加工处理(改变)该消息,也可以不作处理而继续传递该消息,还可以强制结束消息的传递。

这些事件刚好可以为对model实例增删改查的前后进行拦截,然后对model实例做一些加工处理。因此,钩子这个名字正合适。

这些事件都可以通过this来调用model实例本身。

var Person = db.define("person", {
    name    : String,
    surname : String
}, {
    hooks: {
        beforeCreate: function (next) {
            console.log(this.name);
            next();
        }
    }
});

一共9个事件,不是before*就是after*。但从一组来看,先后顺序很好区分,比如beforeCreate和afterCreate,分别是在insert的一前一后。

但是insert并不是仅仅关联beforeCreate和afterCreate这么简单,它还关联afterLoad、beforeVlidation、beforeSave和afterSave,那么谁先谁后呢?

通过程序来区分吧。

hook-insert.js:

var orm = require("orm");

orm.connect('mysql://root:root@localhost:3306/nodejs', function(err, db){
    if (err) throw err;
    var User = db.define("user", {
        id          :{type:'serial', mapsTo:'id', unique:true, size:11},
        name        :{type:'text', mapsTo:'name'},
        username    :{type:'text', mapsTo:'username'},
        password    :{type:'text', mapsTo:'password'},
        birthday    :{type:'date', mapsTo:'birthday', time:true}
    },{
        validations:{
            username:orm.enforce.unique('The username is already existed.')
        },
        hooks:{
            afterLoad : function(next){
                console.log('This is afterLoad');
                next();
            },
            afterAutoFetch : function(next){
                console.log('This is afterAutoFetch')
                next();
            },
            beforeSave:function(next){
                console.log('This is beforeSave')
                next();
            },
            afterSave:function(success){
                console.log('This is afterSave')
            },
            beforeCreate :function(next){
                console.log('This is beforeCreate')
                next();
            },
            afterCreate :function(success){
                console.log('This is afterCreate')
            },
            beforeRemove :function(next){
                console.log('This is beforeRemove')
                next();
            },
            afterRemove :function(success){
                console.log('This is afterRemove')
            },
            beforeValidation :function(next){
                console.log('This is beforeValidation')
                next();
            }
        }
    });

    var user = new User(
        {
            name:'e',
            username:'ee',
            password:'eee',
            birthday:'2010-10-10 10:10:10'
        }
    );
    user.save(function(err){
        if(err){
            console.log(err);
        }
    });

});

运行hook-insert:

node hook-insert.js
This is afterLoad
This is afterAutoFetch
This is beforeValidation
This is beforeCreate
This is beforeSave
This is afterCreate
This is afterSave

hook-load.js:

var orm = require("orm");

orm.connect('mysql://root:root@localhost:3306/nodejs', function(err, db){
    if (err) throw err;
    var User = db.define("user", {
        id          :{type:'serial', mapsTo:'id', unique:true, size:11},
        name        :{type:'text', mapsTo:'name'},
        username    :{type:'text', mapsTo:'username'},
        password    :{type:'text', mapsTo:'password'},
        birthday    :{type:'date', mapsTo:'birthday', time:true}
    },{
        validations:{
            username:orm.enforce.unique('The username is already existed.')
        },
        hooks:{
            afterLoad : function(next){
                console.log('This is afterLoad');
                next();
            },
            afterAutoFetch : function(next){
                console.log('This is afterAutoFetch')
                next();
            },
            beforeSave:function(next){
                console.log('This is beforeSave')
                next();
            },
            afterSave:function(success){
                console.log('This is afterSave')
            },
            beforeCreate :function(next){
                console.log('This is beforeCreate')
                next();
            },
            afterCreate :function(success){
                console.log('This is afterCreate')
            },
            beforeRemove :function(next){
                console.log('This is beforeRemove')
                next();
            },
            afterRemove :function(success){
                console.log('This is afterRemove')
            },
            beforeValidation :function(next){
                console.log('This is beforeValidation')
                next();
            }
        }
    });

    User.find({username:'ee'}, function(err, items) {
        for(var i=0;i<items.length;i++){
            console.log(JSON.stringify(items[i]));
        }
    });

});

运行hook-load.js:

node hook-load.js
This is afterLoad
This is afterAutoFetch
{"id":8,"name":"e","username":"ee","password":"eee","birthday":"2010-10-10T02:10:10.000Z"}

hook-update.js:

var orm = require("orm");

orm.connect('mysql://root:root@localhost:3306/nodejs', function(err, db){
    if (err) throw err;
    var User = db.define("user", {
        id          :{type:'serial', mapsTo:'id', unique:true, size:11},
        name        :{type:'text', mapsTo:'name'},
        username    :{type:'text', mapsTo:'username'},
        password    :{type:'text', mapsTo:'password'},
        birthday    :{type:'date', mapsTo:'birthday', time:true}
    },{
        validations:{
            username:orm.enforce.unique('The username is already existed.')
        },
        hooks:{
            afterLoad : function(next){
                console.log('This is afterLoad');
                next();
            },
            afterAutoFetch : function(next){
                console.log('This is afterAutoFetch')
                next();
            },
            beforeSave:function(next){
                console.log('This is beforeSave')
                next();
            },
            afterSave:function(success){
                console.log('This is afterSave')
            },
            beforeCreate :function(next){
                console.log('This is beforeCreate')
                next();
            },
            afterCreate :function(success){
                console.log('This is afterCreate')
            },
            beforeRemove :function(next){
                console.log('This is beforeRemove')
                next();
            },
            afterRemove :function(success){
                console.log('This is afterRemove')
            },
            beforeValidation :function(next){
                console.log('This is beforeValidation')
                next();
            }
        }
    });

    User.find({username:'ee'}, function(err, items) {
        for(var i=0;i<items.length;i++){
            items[i].username = 'ff';
            items[i].save();
        }
    });

});

运行hook-update.js:

node hook-update.js
This is afterLoad
This is afterAutoFetch
This is beforeValidation
This is beforeSave
This is afterSave

hook-delete.js:

var orm = require("orm");

orm.connect('mysql://root:root@localhost:3306/nodejs', function(err, db){
    if (err) throw err;
    var User = db.define("user", {
        id          :{type:'serial', mapsTo:'id', unique:true, size:11},
        name        :{type:'text', mapsTo:'name'},
        username    :{type:'text', mapsTo:'username'},
        password    :{type:'text', mapsTo:'password'},
        birthday    :{type:'date', mapsTo:'birthday', time:true}
    },{
        validations:{
            username:orm.enforce.unique('The username is already existed.')
        },
        hooks:{
            afterLoad : function(next){
                console.log('This is afterLoad');
                next();
            },
            afterAutoFetch : function(next){
                console.log('This is afterAutoFetch')
                next();
            },
            beforeSave:function(next){
                console.log('This is beforeSave')
                next();
            },
            afterSave:function(success){
                console.log('This is afterSave')
            },
            beforeCreate :function(next){
                console.log('This is beforeCreate')
                next();
            },
            afterCreate :function(success){
                console.log('This is afterCreate')
            },
            beforeRemove :function(next){
                console.log('This is beforeRemove')
                next();
            },
            afterRemove :function(success){
                console.log('This is afterRemove')
            },
            beforeValidation :function(next){
                console.log('This is beforeValidation')
                next();
            }
        }
    });

    User.find({username:'ff'}, function(err, items) {
        for(var i=0;i<items.length;i++){
            items[i].remove();
        }
    });

});

运行hook-delete.js:

node hook-delete.js
This is afterLoad
This is afterAutoFetch
This is beforeRemove
This is afterRemove

从上面增、删、改、查四个程序的运行结果不难看出:

跟insert有关的事件有7个,按顺序分别是afterLoad、afterAutoFetch、beforeValidation、beforeCreate、beforeSave、afterCreate、afterSave。

跟udpate有关的事件有5个,按顺序分别是afterLoad、afterAutoFetch、beforeValidation、beforeSave、afterSave。

跟selete有关的事件有2个,按顺序分别是afterLoad、afterAutoFetch。

跟delete有关的事件有2个,按顺序分别是beforeRemove、afterRemove。

另外,除了afterSave、afterCreate和afterRemove,其他事件都有next参数,next是一个回调函数用于执行下一步,如果没next,程序将就此终止。

时间: 2024-08-11 00:39:13

node.js学习笔记(28) node-orm进阶三的相关文章

Node.js 学习笔记之简介、安装及配置

 本文是Node.js学习笔记系列文章的第一篇,主要给大家讲解的是在Windows和Linux上安装Node.js的方法.软件安装版本以0.12.0为例.希望大家能够喜欢.     简单的说 Node.js 就是运行在服务端的 JavaScript. Node.js 是一个基于Chrome JavaScript 运行时建立的一个平台. Node.js是一个事件驱动I/O服务端JavaScript环境,基于Google的V8引擎,V8引擎执行Javascript的速度非常快,性能非常好. 谁适合阅

node.js学习笔记(9) 和谐模式

众所周知,ECMAScript 是一种开放的.国际上广为接受的脚本语言规范. 它本身并不是一种脚本语言.正如在 Web 应用程序中执行有用操作的 bean 集合(例如,Netscape 的 AWT)是 Sun 的 JavaBean 规范的一种实现一样,JavaScript 是 ECMAScript 规范的一种实现. 2015年6月17日,ECMA国际发布了EcmaScript2015,即EcmaScript6(以下简称ES6)草案的正式版.ES6是继ES5之后的一次主要改进,语言规范由ES5.1

Node.js学习笔记(一)概述

什么是Node.JS? 引用豆瓣Node.JS小组的回答: 把事件驱动IO库绑定给V8 JavaScript虚拟机实现的通用编程环境. 2月10日发布的0.4.0版成为新的稳定分支, 已更新至0.4.12 非稳定分支开始加入原生 Windows 支持, 已更新至0.5.6 官方网站, 包括API文档, 邮件列表等:http://nodejs.org 项目地址: https://github.com/joyent/node 它有什么不同? * 网络通信与文件系统IO无阻塞, 避免CPU时间浪费.

node.js学习笔记(7) 事件机制

在web前端的编程中,事件的应用十分广泛,DOM上的各种事件,比如onclick .onfocus等等. 在ajax大规模应用之后,异步请求更是得到广泛的认同,而ajax亦是基于事件机制的. Node.js的事件机制是基于V8引擎实现的事件驱动I/O,充分呢利用了异步I/O解决了单线程编程模型的性能瓶颈. 事件机制的实现 Node.js内置了events模块,Events模块(events.EventEmitter)是一个简单的事件监听器模式的实现.具有addListener/on,once,r

node.js学习笔记(26) node-orm进阶一

上一个笔记中,我们已经认识了node-orm,它可以支持mongodb.mysql.postgres.  redshift. _shared和sqlite. 之所以能支持这么多中数据库,是因为node-orm的lib中有对各种数据库支持的backend脚本,可以看一下orm/lib/Drivers/DML目录下的文件有mongodb.js.mysql.js.postgres.js.redshift.js._shared.js.sqlite.js.这其中的每一个脚本其实都是对各种数据库驱动的封装,

node.js学习笔记(16) child_process(三)

学习过前两篇笔记的源码分析,再来应用child_process的7个方法就不难理解了. By default, pipes for stdin, stdout and stderr are established between the parent Node.js process and the spawned child. 默认情况下,Node.js主进程和子进程间就会建立三个管道:stdin.stdout和stderr,即标准输入流.标准输出流和标准错误流. 如今热播的<芈月传>中有一段

node.js学习笔记(0) 前记

学习笔记原本是从1开始的,然而为了永远"怀念"已经离职的钱童鞋,我决定补上一篇.话说,程序员的数数不都是从0开始的吗. 初识node.js大概是一年前的这个时候,钱童鞋来单位面试,简历上的其中一项技能是node.js.当时我还傻傻的以为又是一个类似jquery的js框架-- 过完年,钱童鞋入职,然后慢慢得熟悉,交流得越来越多,也就慢慢得知node.js的众多优点. google的V8引擎 高速IO 非阻塞 异步回调 单线程 事件驱动 ... 然并卵,吸引我的却是javascript.在

node.js学习笔记(24) 箭头函数

11月下旬,我安装了Node.js-v5.1.0开始学习和使用Node.js. 然而Node.js开发团队在12月发布了v5.1.1,v5.2.0,v5.3.0,16年1月又发布了v5.4.0,v5.4.1,v5.5.0.这速度,是要坐火箭才能赶上呀-- 言归正传,第一次看到"=>"这个符号是在v5.4.0的api文档中.文档中频繁出现这样的代码示例: ()=>{ ... } 通过查Node.js的更新说明得知,这就是箭头函数,是ES6的新特性,Node.js从v5.4.0

node.js学习笔记(25) express与数据库

Express是一个非常好用的web框架,它可以应用与网站.博客.管理系统等等.当我们开发网站等应用的时候,一般都会用数据库来保存数据.这时就需要jdbc这样的驱动来保存连接数据库. Npmjs.com上提供了丰富的第三方模块,mysql模块就是其中之一,它与mysql数据库同名,是mysql数据库的驱动,用javascript编写的,无需编译. Hello mysql 先来创建一个mysql的示例, 创建一个nodejs-mysql工程: mkdir nodejs-mysql cd nodej

node.js学习笔记(13) global objects

Global objects可简单地译为全局对象,但它又不全是全局对象.Global objects 其实包括真正的全局对象和模块级的全局对象. 来看看它们分别有哪些吧. 真正的全局对象 Class: Buffer setInterval(cb, ms) setTimeout(cb, ms) clearInterval(t) clearTimeout(t) console global process 模块级的全局变量 __dirname __filename require() module