nodejs-ORM 操作数据库中间件waterline的使用

waterline和Sails.js同一团队开发,支持几乎所有的主流数据库,是nodejs下一款非常强大的orm,可以显著提升开发效率

一.waterline支持的数据库

二.waterline的配置

Waterline 之所以可以使用一样的代码来操作多种数据库,奥妙在于其适配器。在进行配置的时候,需要设置两方面的内容,一是具体使用哪些适配器,二是建立数据库连接的时候,使用哪个适配器。下面是使用 MongoDB/Mysql 的适配器创建一个数据库连接的配置

MongoDB:

 1 var mongoAdapter = require('sails-mongo');
 2 var wlconfig = {
 3   adapters: {
 4     'default': mongoAdapter,
 5     'mongo': mongoAdapter
 6   },
 7   connections: {
 8     'mongo': {
 9       // adapters 中的适配器代码
10       adapter: 'mongo',
11       url: 'mongodb://localhost/waterline-sample'
12     }
13   }
14 };
sails-mongo 为mongo的适配器,执行命令安装:
npm i sails-mongo --save

Mysql:

 1 var mysqlAdapter = require('sails-mysql');
 2 var Waterline = require('waterline');
 3 
 4 var icbcgold = require('../models/IcbcGold')
 5 
 6 //适配器与连接设置
 7 var wlconfig = {
 8     adapters: {
 9         mysql: mysqlAdapter, //mysql适配器
10         default: 'mysql' //默认的适配器
11     },
12     connections: {
13         //mysql连接
14         mysql: {
15             adapter: 'mysql',//指定适配器为mysql
16             url: 'mysql://root:@localhost/IcbcGold' //连接字符串
17         }
18     }
19 }
sails-mysql 为mysql适配器,执行命令安装:
1 npm i sails-mysql --save

 连接字符串说明:数据库类型://用户名:密码@数据库地址/数据库名

三.waterline的Model的定义

执行命令安装waterline:

npm i waterline --save
 1 var Waterline = require('waterline');
 2 
 3 module.exports = Waterline.Collection.extend({
 4     identity: 'icbcgold',  //模型名,如果没有设置 tableName 属性,那么waterline默认将模型名设置为表名
 5     tableName: 'tb_IcbcGold',//指定表名
 6     connection: 'mysql',//指定数据库连接
 7     // 是否强制模式
 8     schema: false,
 9     attributes: {
10         Id: {
11             type: 'string',
12             primaryKey: true
13         },
14         DataTime: {
15             type: 'datetime'
16         },
17         DataNumber: {
18             type: 'float'
19         }
20     }
21 });

配置相当简单方便,类似于 Mongoose 中的 Schema。但要注意,指定属性的字段时,使用的是一个字符串值,而不是 JavaScript 中的具体类型,目前支持的数据类型有 string / text / integer / float / date /time / datetime / boolean / binary / array / json,这个范围要比 JavaScript 的类型范围大。

除了这四个基本配置,还可以配置校验器,添加自定义的方法,设置生命周期回调方法等。

注意:

  1.如果没有定义主键,那么waterline会为你默认创建名为id的主键,类型是整型自增长

  2.waterline自动创建表时会为你添加 createdAt、updatedAt两个字段,类型为datetime,分别在insert和update操作更新字段代表的是记录的创建时间和更新时间

  3.如果不想自动创建列createdAt、updatedAt,那么请设置autoCreatedAt,autoUpdatedAt的值为false,如下图

  4.waterline会自动根据定义的model创建表,但是如果你已经创建好了表,但是与model定义有所区别,比如字段名不一样,那么一定要注意了,请按照下图设置,否则waterline将会删除已经存在表且根据model重新创建,以前的数据就完蛋了

四.校验器

校验器是在创建数据集合的时候指定给具体的属性的

更多设置请查看:https://www.npmjs.com/package/waterline

 1 attributes: {
 2         title: {
 3             type: 'string',
 4             required: true,//必须的字段
 5             maxLength: 100,//最大长度100
 6             minLength: 5 //最小长度5
 7         },
 8         views: {
 9             type: 'integer',
10             min: 0
11         },
12         createTime: {
13             type: 'date',
14             // 在某个时间点之前
15             before: '2017-12-31', 
16             // 在某个时间点之后
17             after: function () {
18                 return new Date();
19             }
20         }
21     }

五.生命周期回调

 可以通过waterline,来实现在进行特定操作的时候,调用自定义的方法。,在 create / update / destory时,均有多种回调。直接提供对应的方法名,分别是:

  • 创建时:beforeValidate / afterValidate / beforeCreate / afterCreate
  • 更新时:beforeValidate / afterValidate / beforeUpdate / afterUpdate
  • 删除时:beforeDestroy / afterDestroy

这些方法,需要在初始化数据集合的时候进行定义。

 1 //values值 cb回调方法
 2 beforeCreate: function(values, cb) {
 3  
 4     // 加密password字段的值
 5     encrypt(values.password, function(err, password) {
 6       if(err) return cb(err);
 7  
 8       values.password = password;
 9       cb();
10     });
11   },

六.查询方法

waterline有以下查询方法

1.查询 name 等于 foo 的记录

Model.find({ name: 'foo' })

 2.多条件查询 查询 name 等于 water 并且 state 等于new mexico 的记录

1 Model.find({ name: 'walter', state: 'new mexico' })
User.find()
.where({ id: { '>': 100 }})
.where({ age: 21 })
.limit(100)
.sort('name')
.exec(function(err, users) {
  // Do stuff here 
});

下面的修饰符可用于构建查询时使用。

  • '<' / '小于'
  • '<=' / '小于等于'
  • '>' / '大于'
  • '>=' / '大于等于'
  • '!' / '非'
  • 'like'/'模糊匹配'
  • 'contains'/'包含'
  • 'startsWith'/'以某字符开头'
  • 'endsWith'/'以某字符结尾'

 3.分页查询

1 User.find().skip(10).limit(10); //跳过10条记录 取10条记录
1 Model.find({ where: { name: 'foo' }, skip: 20, limit: 10, sort: 'name DESC' });//带条件分页查询
User.find().paginate({page: 2, limit: 10});//根据页数分页查询

 4.新增记录

User.create({Id:'xxx',Name:'xxx'});

5.更新记录

User.update({ name: 'Walter Jr' }, { name: 'Flynn' })

6.删除记录

User.destroy({ name: 'Flynn' })

Promises

 1 User.findOne()
 2 .where({ id: 2 })
 3 .then(function(user){
 4     var comments = Comment.find({userId: user.id}).then(function(comments){
 5         return comments;
 6     });
 7     return [user.id, user.friendsList, comments];
 8 }).spread(function(userId, friendsList, comments){
 9     // Promises are awesome! 
10 }).catch(function(err){
11     // An error occurred 
12 })

七.使用示例

这里使用的数据库是mysql创建一个数据库名为:IcbcGold

1.新建一个js文件:waterline.js,代码如下:

 1 var mysqlAdapter = require('sails-mysql');
 2 var Waterline = require('waterline');
 3 
 4 var icbcgold = require('../models/IcbcGold')
 5 
 6 //适配器与连接设置
 7 var wlconfig = {
 8     adapters: {
 9         mysql: mysqlAdapter, //mysql适配器
10         default: 'mysql' //默认的适配器
11     },
12     connections: {
13         //mysql连接
14         mysql: {
15             adapter: 'mysql',//指定适配器为mysql
16             url: 'mysql://root:@localhost/IcbcGold' //连接字符串
17         }
18     }
19 }
20 
21 var orm = new Waterline();
22 
23 //加载model集合
24 orm.loadCollection(icbcgold);
25 
26 exports.orm = orm;
27 exports.wlconfig = wlconfig;

2.新建文件 index.js

var waterline = require('./app/config/waterline');
var uuid = require('uuid');


var ormmodels = null;

//初始化waterline
waterline.orm.initialize(waterline.wlconfig, function (err, models) {
    if (err) {
        return;
    }
    ormmodels = models.collections;
})
//执行查询
ormmodels.icbcgold.count({ DataTime: dataTime }).exec(function (err, found) {
        if (err) {
            return;
        }
        if (found === 0) {
            ormmodels.icbcgold.create({ Id: uuid.v1(), DataTime: dataTime, DataNumber: dataNumber }, function (err, models) {
                if (err) {
                    return;
                }
            });
        }
    });

 呼~~~~终于写完了,下面帖几个网址,如果你有什么问题可以先查看

http://sailsjs.com/documentation/reference/waterline-orm/models

https://www.npmjs.com/package/waterline

waterline使用是非常简单的,目前用nodejs写了一个爬虫,使用waterline存储数据到mysql,已经部署到服务器上,使用pm2运行,抓取数据用的是superagent,后面我会继续写如果用nodejs写爬虫,欢迎关注!

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏技术博文

PHP漏洞全解

针对PHP的网站主要存在下面几种攻击方式: 1、命令注入(Command Injection) 2、eval注入(Eval Injection) 3...

3997
来自专栏Java3y

Hibernate面试题大全

Hibernate常见面试题 Hibernate工作原理及为什么要用? Hibernate工作原理及为什么要用? 读取并解析配置文件 读取并解析映射信息,创建...

3635
来自专栏YoungGy

R包简单教程

R包概述 R包是什么 为什么学习R包 R包的结构 R包的工作流程 R包的创建 预先准备 包的创建 DESCRIPTION的编写 数据文件 R函数 R文档 测试R...

30410
来自专栏黑泽君的专栏

day56_BOS项目_08

  注意1:权限数据属于比较特殊的数据,系统在上线之后,必须先把权限数据给它初始化到数据库中去,然后这个系统才可以跑起来。如果不初始化权限数据的话,那么登录上系...

912
来自专栏枕边书

从并发处理谈PHP进程间通信(一)外部介质

进程间通信 进程间通信(IPC,Inter-Process Communication),多进程开发中,进程间通信是一个永远也绕不开的问题。在 web开发中,我...

2546
来自专栏DOTNET

【翻译】MongoDB指南/CRUD操作(二)

【原文地址】https://docs.mongodb.com/manual/ MongoDB CRUD操作(二) 主要内容: 更新文档,删除文档,批量写操作,S...

3218
来自专栏北京马哥教育

27个Linux文档编辑命令

在许多UNIX说明文件里,都有RLF控制字符。当我们运用shell特殊字符">"和">>",把说明文件的内容输出成纯文本文件时,控制字符会变成乱码,col指令则...

1225
来自专栏JackeyGao的博客

Celery用户手册 - Tasks

Tasks是Celery 应用的构建块。事实上Celery应用是由一个或多个Task拼装组成的。

1303
来自专栏积累沉淀

Oracle递归查询:使用prior实现树操作

oracle树查询的最重要的就是select…start with…connect by…prior语法了。依托于该语法,我们可以将一个表形结构的数据以树的顺...

2775
来自专栏魏琼东

一步一步教你使用AgileEAS.NET基础类库进行应用开发-WinForm应用篇-实现字典的打印

系列回顾          从上一篇文章一步一步教你使用AgileEAS.NET基础类库进行应用开发-WinForm应用篇-实例一个模块(商品字典)开始我带领大...

2005

扫码关注云+社区