数据库连接

  1. var orm = require("orm");
  2.  
  3. orm.connect("mysql://username:password@host/database", function (err, db) {
  4. }

实际情况: 由于公司产品比较多,每个产品就会有一个数据库,所以我们做底层的必须连接各个产品的数据库。

所以解决方案:

1.配置文件中将所有数据库都配置好,如下:

  1. server: {
  2. mysql: {
  3. product: {
  4. host: '',
  5. user: '',
  6. password: '',
  7. database: '',
  8. port: 3306,
  9. multipleStatements: true,
  10. insecureAuth: true
  11. },
  12. ss: {
  13. host: '',
  14. user: '',
  15. password: '',
  16. database: '',
  17. port: 3306,
  18. multipleStatements: true,
  19. insecureAuth: true
  20. }
  21. }
  22. }

2.定义全局DB操作对象

  1. global.dbs = {};

3.通过bluebird,underscore等包,类似循环连接数据库,并保存链接,下面为部分代码

  1. var _ = require('underscore'),
  2. promise = require('bluebird');
  3.  
  4. /**
  5. * 初始化数据库连接
  6. * @param conn 数据库连接字符串
  7. * @param dbServer 数据库服务器
  8. * @param callback
  9. */
  10. var toDB = function (conn, dbServer, callback) {
  11. orm.connect(conn, function (err, db) {
  12. //连接错误,则抛出异常
  13. if (err) return comm.nextTick(err, callback);
  14. //将数据库连接存入全局数据库连接对象中
  15. dbs[dbServer] = db;
  16. comm.nextTick(null, dbs, callback);
  17. })
  18. }
  19.  
  20. //toDB函数promise化
  21. var toDBPrms = promise.promisify(toDB);
  22.  
  23. //?pool=true为开启连接池
  24. var connections = _.map(config.server.mysql, function (connection, key) {
  25. return toDBPrms('mysql://' + connection.user + ':' + connection.password + '@' + connection.host + '/' + connection.database + '?pool=true', key);
  26. });
  27.  
  28. promise
  29. .all(connections)
  30. .then(function () {
  31. console.log('数据库连接成功');
  32. })
  33. .catch(function (err) {
  34. log.error({'数据库连接错误:': JSON.stringify(err)});
  35. })

Model定义

官方的Model加载定义是在连接数据库的时候,如下:

  1. orm.connect("mysql://username:password@host/database", function (err, db) {
  2. if (err) throw err;
  3.  
  4. var Person = db.define("person", {
  5. name : String,
  6. surname : String,
  7. age : Number, // FLOAT
  8. male : Boolean,
  9. continent : [ "Europe", "America", "Asia", "Africa", "Australia", "Antartica" ], // ENUM type
  10. photo : Buffer, // BLOB/BINARY
  11. data : Object // JSON encoded
  12. } .......

可是这样太冗余,对于大项目表又多的情况明显不合适,所以它还有一种加载定义Model方式,即Model作为单独的一个文件。

  1. //定义表结构Model
  2. module.exports = function (db, cb) {
  3. //define方法的第一个参数为表名
  4. db.define('xxx', {
  5. innerid: { type: 'serial', key: true } , //主键
  6. name: String,
  7. identifying: String,
  8. purpose_code: Number,
  9. org_id: String,
  10. position_x: Number,
  11. position_y: Number,
  12. isenabled: Number,
  13. isdeleted: Number
  14. });
  15. return cb();
  16. }

加载

  1. //db为数据库连接,相当于connection; load第一个参数为Model的路径
  2. db.load('XXX', function (err) {
  3. //加载model错误,记录异常
  4. if (err) {
  5. return callback(err,xxx);
  6. }
  7. callback(null,xxx);
  8. })

数据插入

Model.Create:

  1. Person.create([
  2. {
  3. name: "John",
  4. surname: "Doe",
  5. age: 25,
  6. male: true
  7. },
  8. {
  9. name: "Liza",
  10. surname: "Kollan",
  11. age: 19,
  12. male: false
  13. }
  14. ], function (err, items) {
  15. // err - description of the error or null
  16. // items - array of inserted items
  17. });

下面是我对其进行封装

  1. /**
  2. * 数据添加
  3. * @param dbServer db服务器
  4. * @param modelName model名字
  5. * @param entity 插入数据(JSON格式)
  6. * @param callback 返回结果
  7. */
  8. daoComm.prototype.create = function (dbServer, modelName, entity, callback) {
  9. //数据库连接,dbs里面存了各个产品的数据库,所以要获取对应的数据库连接
  10. var db = dbs[dbServer];
  11. //连接不存在,则抛错
  12. if (!db) return comm.nextTick(comm.response(config.status.FAILURE, 'DB Connection IS NOT Exist'), callback);
  13. //model没加载,则自动加载
  14. if (!db.models[modelName]) {
  15. //加载model
  16. loadModel(db, dbServer, modelName, function (err) {
  17. //如有错误,则返回
  18. if (err) return comm.nextTick(err, callback);
  19. //执行插入数据操作
  20. add(db.models[modelName], modelName, entity, callback);
  21. });
  22. } else {
  23. //执行插入数据操作
  24. add(db.models[modelName], modelName, entity, callback);
  25. }
  26. }
  27. /**
  28. * 实际插入数据操作
  29. * @param model model对象
  30. * @param modelName 表名
  31. * @param entity 插入数据
  32. * @param callback 返回值
  33. */
  34. function add(model, modelName, entity, callback) {
  35. model.create(entity, function (err, resItems) {
  36. if (err) return comm.nextTick(comm.response(config.status.FAILURE, modelName + ' Data Insert ERROR : ' + err), callback);
  37. return comm.nextTick(null, comm.response(config.status.OK, resItems), callback);
  38. })
  39. }

数据查找

1.Model.get(第一个参数为id的值):

  1. Person.get(4, function(err, person) {
  2. console.log( person.fullName() );
  3. })

2.Model.find([ conditions ] [, options ] [, limit ] [, order ] [, cb ])

  1. Person.find({ name: "John", surname: "Doe" }, 3, function (err, people) {
  2. // finds people with name='John' AND surname='Doe' and returns the first 3
  3. });

3.Model.find链式写法

  1. Person.find({ surname: "Doe" }).limit(3).offset(2).only("name", "surname").run(function (err, people) {
  2. // finds people with surname='Doe', skips first 2 and limits to 3 elements,
  3. // returning only 'name' and 'surname' properties
  4. });

这里数据查找的方法比较多。要再次封装的时候头很大,封装链式太麻烦;封装第二个find方法,参数又不固定,如何只取当中几列啥的文档也没写清楚,原来limit,offset,only这些都能放在options里面,所以最后还是看底层源码解决的...

  1. /**
  2. * 数据查询
  3. * @param dbServer db服务器
  4. * @param modelName model名字
  5. * @param conditions 查询条件(json)
  6. * @param options 查询选项(json) {"offset":2,"limit":3,"only":["innerid","name"]} offset跳过条数 limit查询条数 only:取的列
  7. * @param order 排列(object) 例:["name","Z"],按name倒序
  8. * 备注 传入的conditions,options,order都必须json.parse一下
  9. * @param callback 返回结果
  10. */
  11. daoComm.prototype.find = function (dbServer, modelName, conditions, options, order, callback) {
  12. //数据库连接
  13. var db = dbs[dbServer];
  14. //连接不存在,则抛错
  15. if (!db) return comm.nextTick(comm.response(config.status.FAILURE, 'DB Connection IS NOT Exist'), callback);
  16. //参数没有时初始化
  17. if (!conditions) conditions = {};
  18. if (!options) options = {};
  19. if (!order) order = [];
  20. //判断参数类型
  21. if (typeof conditions != "object" || typeof options != "object" || typeof order != "object") {
  22. return comm.nextTick(comm.response(config.status.FAILURE, 'TypeOf Param Error'), callback);
  23. }
  24. //model没加载,则自动加载
  25. if (!db.models[modelName]) {
  26. //加载model
  27. loadModel(db, dbServer, modelName, function (err) {
  28. //如有错误,则返回
  29. if (err) return comm.nextTick(err, callback);
  30. //执行查询数据操作
  31. query(db.models[modelName], modelName, conditions, options, order, callback);
  32. });
  33. } else {
  34. //执行查询数据操作
  35. query(db.models[modelName], modelName, conditions, options, order, callback);
  36. }
  37. }
  1. /**
  2. * 实际查询数据操作
  3. * @param model model对象
  4. * @param modelName 表名
  5. * @param conditions 查询条件
  6. * @param options 查询选项
  7. * @param order 排序
  8. * @param callback
  9. */
  10. function query(model, modelName, conditions, options, order, callback) {
  11. model.find(conditions, options, order, function (err, data) {
  12. if (err) return comm.nextTick(comm.response(config.status.FAILURE, modelName + ' Data Query ERROR : ' + err), callback);
  13. return comm.nextTick(null, comm.response(config.status.OK, data), callback);
  14. })
  15. }

可能这种封装方式也不好,希望各位大大能给点建议看看还有木有更好的~~

数据删除

简单来说就是先查后删Model.find().remove();

  1. Person.find({ surname: "Doe" }).remove(function (err) {
  2. // Does gone..
  3. });

数据更新

稍微有点麻烦,先查后遍历修改再保存 Model.find().each().save()

  1. Person.find({ surname: "Doe" }).each(function (person) {
  2. person.surname = "Dean";
  3. }).save(function (err) {
  4. // done!
  5. });

取COUNT

Model.find().count()

  1. Person.find({ surname: "Doe" }).count(function (err, people) {
  2. // people = number of people with surname="Doe"
  3. });

判断是否存在

Model.Exists([ conditions, ] cb)

  1. Person.exists({ surname: "Doe" }, function (err, exists) {
  2. console.log("We %s Does in our db", exists ? "have" : "don't have");
  3. });

函数使用

Model.aggregate

  1. Person.aggregate({ surname: "Doe" }).min("age").max("age").get(function (err, min, max) {
  2. console.log("The youngest Doe guy has %d years, while the oldest is %d", min, max);
  3. });
  4.  
  5. //The same as "select avg(weight), age from person where country='someCountry' group by age;"
  6. Person.aggregate(["age"], { country: "someCountry" }).avg("weight").groupBy("age").get(function (err, stats) {
  7. // stats is an Array, each item should have 'age' and 'avg_weight'
  8. });

官方给出这几个函数:min、max、avg、sum、count

groupBy只能在Model.aggregate中使用

多表查询

hasOne()、hasMany(),很遗憾,限制太多(具体哪些,自己去踩坑吧)俺不搞!

多表查询替代方法 && 直接执行SQL

db.driver.execQuery

按 Ctrl+C 复制代码
按 Ctrl+C 复制代码

Sequelize也接触过一点点,不过感觉没ORM2上手那么容易,而且感觉ORM2的坑比较少 哈哈。

由于比较菜,各位在看本人自己封装的代码时吐槽时嘴下留情。 希望也能给本人多些建议,tks~

orm2的更多相关文章

  1. koa中间件系统原理及koa+orm2实践。

    koa是由 Express 原班人马打造的新的web框架.套用其官方的说法:Koa 应用是一个包含一系列中间件 generator 函数的对象. 这些中间件函数基于 request 请求以一个类似于栈 ...

  2. koa+orm2

    koa+orm2 koa是由 Express 原班人马打造的新的web框架.套用其官方的说法:Koa 应用是一个包含一系列中间件 generator 函数的对象. 这些中间件函数基于 request ...

  3. node中通过orm2链接mysql的一个坑

    代码是orm上的例子,出现如下错误: ORMError: Connection protocol not supported - have you installed the database dri ...

  4. Hibernate 系列 02 - Hibernate介绍及其环境搭建

    引导目录: Hibernate 系列教程 目录 昨晚喝多了,下午刚清醒,继续搞Hibernate.走起. 觉得还行的话,记得点赞哈,给我这个渣渣点学习的动力.有错误的话也请指出,省的我在错误上走了不归 ...

  5. docker核心原理

    容器概念. docker是一种容器,应用沙箱机制实现虚拟化.能在一台宿主机里面独立多个虚拟环境,互不影响.在这个容器里面可以运行着我饿们的业务,输入输出.可以和宿主机交互. 使用方法. 拉取镜像 do ...

  6. 开源框架】Android之史上最全最简单最有用的第三方开源库收集整理,有助于快速开发

    [原][开源框架]Android之史上最全最简单最有用的第三方开源库收集整理,有助于快速开发,欢迎各位... 时间 2015-01-05 10:08:18 我是程序猿,我为自己代言 原文  http: ...

  7. [转]为什么我要用 Node.js? 案例逐一介绍

    原文地址:http://blog.jobbole.com/53736/ 介绍 JavaScript 高涨的人气带来了很多变化,以至于如今使用其进行网络开发的形式也变得截然不同了.就如同在浏览器中一样, ...

  8. Android 第三方开源库收集整理(转)

    原文地址:http://blog.csdn.net/caoyouxing/article/details/42418591 Android开源库 自己一直很喜欢Android开发,就如博客签名一样,  ...

  9. 【转】为什么我要用 Node.js? 案例逐一介绍

    原文转自:http://blog.jobbole.com/53736/ 介绍 JavaScript 高涨的人气带来了很多变化,以至于如今使用其进行网络开发的形式也变得截然不同了.就如同在浏览器中一样, ...

随机推荐

  1. 【转】android中TextAppearanceSpan的使用

    android中TextAppearanceSpan的使用 Posted on April 17, 2011 在android中如何想word中一样对文字进行丰富的风格设置呢? TextAppeara ...

  2. rapid-framework脚手架快速搭建springMVC框架项目

    rapid-framework介绍:   一个类似ruby on rails的java web快速开发脚手架,本着不重复发明轮子的原则,框架只是将零散的struts(struts2)+spring+h ...

  3. Visual Studio 编辑器

    如何扩展 Visual Studio 编辑器 在 Visual Studio 2010 的时代,扩展 Visual Studio 的途径有很多,开发者可以选择宏.Add-in.MEF 和 VSPack ...

  4. Mocha JavaScript TDD

    JavaScript TDD with Mocha 2014-04-30 02:05 by owenyang, 317 阅读, 0 评论, 收藏, 编辑 开发现状 当新的版本快要发布的时候,大家都忙于 ...

  5. java编程思想笔记(第一章)

    Alan Kay 第一个定义了面向对象的语言 1.万物皆对象 2.程序是对象的集合,他们彼此通过发送消息来调用对方. 3.每个对象都拥有由其他对象所构成的存储 4.每个对象都拥有其类型(TYpe) 5 ...

  6. NUnit使用方法

    单元测试是一个成熟项目必不可少的一个环节,NUnit很好的提供了测元测试的一些方法,以下是我得出的一点点经验以及NUnit的一点点实际应用中用到的内容.写的有点儿乱,不懂下面留言.谢谢~ 准备NUni ...

  7. C#方法同步 [MethodImpl(MethodImplOptions.Synchronized)]

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  8. 玩转python之字符串逐个字符或逐词反转

    众所周知,python中的字符串是无法改变的,反转一个字符串自然要创建一个拷贝:最简单的方法,当然是步长为“-1”的切片: result = astring[::-1] 如果要是按单词来反转,需要三步 ...

  9. 设计适用于SOA的类型(二)

    接着上次的,以扩展String类型为例,继续根据自己的使用习惯闭门造车!   这一次我重载了运算符 = 和 + ,我觉得这样更方便我的使用.首先先贴代码: /// <summary> // ...

  10. [google面试CTCI] 1-5.替换字符串中特定字符

    [字符串与数组] Q:Write a method to replace all spaces in a string with ‘%20’ 题目:写一个算法将一个字符串中的空格替换成%20 解答: ...