var orm = require("orm"); orm.connect("mysql://username:password@host/database", function (err, db) { }
實際狀況: 因爲公司產品比較多,每一個產品就會有一個數據庫,因此咱們作底層的必須鏈接各個產品的數據庫。mysql
因此解決方案:sql
1.配置文件中將全部數據庫都配置好,以下:數據庫
server: { mysql: { product: { host: '', user: '', password: '', database: '', port: 3306, multipleStatements: true, insecureAuth: true }, ss: { host: '', user: '', password: '', database: '', port: 3306, multipleStatements: true, insecureAuth: true } } }
2.定義全局DB操做對象json
global.dbs = {};
3.經過bluebird,underscore等包,相似循環鏈接數據庫,並保存連接,下面爲部分代碼promise
var _ = require('underscore'), promise = require('bluebird'); /** * 初始化數據庫鏈接 * @param conn 數據庫鏈接字符串 * @param dbServer 數據庫服務器 * @param callback */ var toDB = function (conn, dbServer, callback) { orm.connect(conn, function (err, db) { //鏈接錯誤,則拋出異常 if (err) return comm.nextTick(err, callback); //將數據庫鏈接存入全局數據庫鏈接對象中 dbs[dbServer] = db; comm.nextTick(null, dbs, callback); }) } //toDB函數promise化 var toDBPrms = promise.promisify(toDB); //?pool=true爲開啓鏈接池 var connections = _.map(config.server.mysql, function (connection, key) { return toDBPrms('mysql://' + connection.user + ':' + connection.password + '@' + connection.host + '/' + connection.database + '?pool=true', key); }); promise .all(connections) .then(function () { console.log('數據庫鏈接成功'); }) .catch(function (err) { log.error({'數據庫鏈接錯誤:': JSON.stringify(err)}); })
官方的Model加載定義是在鏈接數據庫的時候,以下:服務器
orm.connect("mysql://username:password@host/database", function (err, db) { if (err) throw err; var Person = db.define("person", { name : String, surname : String, age : Number, // FLOAT male : Boolean, continent : [ "Europe", "America", "Asia", "Africa", "Australia", "Antartica" ], // ENUM type photo : Buffer, // BLOB/BINARY data : Object // JSON encoded } .......
但是這樣太冗餘,對於大項目表又多的狀況明顯不合適,因此它還有一種加載定義Model方式,即Model做爲單獨的一個文件。ide
//定義表結構Model module.exports = function (db, cb) { //define方法的第一個參數爲表名 db.define('xxx', { innerid: { type: 'serial', key: true } , //主鍵 name: String, identifying: String, purpose_code: Number, org_id: String, position_x: Number, position_y: Number, isenabled: Number, isdeleted: Number }); return cb(); }
加載函數
//db爲數據庫鏈接,至關於connection; load第一個參數爲Model的路徑 db.load('XXX', function (err) { //加載model錯誤,記錄異常 if (err) { return callback(err,xxx); } callback(null,xxx); })
Model.Create:ui
Person.create([ { name: "John", surname: "Doe", age: 25, male: true }, { name: "Liza", surname: "Kollan", age: 19, male: false } ], function (err, items) { // err - description of the error or null // items - array of inserted items });
下面是我對其進行封裝spa
/** * 數據添加 * @param dbServer db服務器 * @param modelName model名字 * @param entity 插入數據(JSON格式) * @param callback 返回結果 */ daoComm.prototype.create = function (dbServer, modelName, entity, callback) { //數據庫鏈接,dbs裏面存了各個產品的數據庫,因此要獲取對應的數據庫鏈接 var db = dbs[dbServer]; //鏈接不存在,則拋錯 if (!db) return comm.nextTick(comm.response(config.status.FAILURE, 'DB Connection IS NOT Exist'), callback); //model沒加載,則自動加載 if (!db.models[modelName]) { //加載model loadModel(db, dbServer, modelName, function (err) { //若有錯誤,則返回 if (err) return comm.nextTick(err, callback); //執行插入數據操做 add(db.models[modelName], modelName, entity, callback); }); } else { //執行插入數據操做 add(db.models[modelName], modelName, entity, callback); } } /** * 實際插入數據操做 * @param model model對象 * @param modelName 表名 * @param entity 插入數據 * @param callback 返回值 */ function add(model, modelName, entity, callback) { model.create(entity, function (err, resItems) { if (err) return comm.nextTick(comm.response(config.status.FAILURE, modelName + ' Data Insert ERROR : ' + err), callback); return comm.nextTick(null, comm.response(config.status.OK, resItems), callback); }) }
1.Model.get(第一個參數爲id的值):
Person.get(4, function(err, person) { console.log( person.fullName() ); })
2.Model.find([ conditions ] [, options ] [, limit ] [, order ] [, cb ])
Person.find({ name: "John", surname: "Doe" }, 3, function (err, people) { // finds people with name='John' AND surname='Doe' and returns the first 3 });
3.Model.find鏈式寫法
Person.find({ surname: "Doe" }).limit(3).offset(2).only("name", "surname").run(function (err, people) { // finds people with surname='Doe', skips first 2 and limits to 3 elements, // returning only 'name' and 'surname' properties });
這裏數據查找的方法比較多。要再次封裝的時候頭很大,封裝鏈式太麻煩;封裝第二個find方法,參數又不固定,如何只取當中幾列啥的文檔也沒寫清楚,原來limit,offset,only這些都能放在options裏面,因此最後仍是看底層源碼解決的...
/** * 數據查詢 * @param dbServer db服務器 * @param modelName model名字 * @param conditions 查詢條件(json) * @param options 查詢選項(json) {"offset":2,"limit":3,"only":["innerid","name"]} offset跳過條數 limit查詢條數 only:取的列 * @param order 排列(object) 例:["name","Z"],按name倒序 * 備註 傳入的conditions,options,order都必須json.parse一下 * @param callback 返回結果 */ daoComm.prototype.find = function (dbServer, modelName, conditions, options, order, callback) { //數據庫鏈接 var db = dbs[dbServer]; //鏈接不存在,則拋錯 if (!db) return comm.nextTick(comm.response(config.status.FAILURE, 'DB Connection IS NOT Exist'), callback); //參數沒有時初始化 if (!conditions) conditions = {}; if (!options) options = {}; if (!order) order = []; //判斷參數類型 if (typeof conditions != "object" || typeof options != "object" || typeof order != "object") { return comm.nextTick(comm.response(config.status.FAILURE, 'TypeOf Param Error'), callback); } //model沒加載,則自動加載 if (!db.models[modelName]) { //加載model loadModel(db, dbServer, modelName, function (err) { //若有錯誤,則返回 if (err) return comm.nextTick(err, callback); //執行查詢數據操做 query(db.models[modelName], modelName, conditions, options, order, callback); }); } else { //執行查詢數據操做 query(db.models[modelName], modelName, conditions, options, order, callback); } }
/** * 實際查詢數據操做 * @param model model對象 * @param modelName 表名 * @param conditions 查詢條件 * @param options 查詢選項 * @param order 排序 * @param callback */ function query(model, modelName, conditions, options, order, callback) { model.find(conditions, options, order, function (err, data) { if (err) return comm.nextTick(comm.response(config.status.FAILURE, modelName + ' Data Query ERROR : ' + err), callback); return comm.nextTick(null, comm.response(config.status.OK, data), callback); }) }
可能這種封裝方式也很差,但願各位大大能給點建議看看還有木有更好的~~
簡單來講就是先查後刪Model.find().remove();
Person.find({ surname: "Doe" }).remove(function (err) { // Does gone.. });
稍微有點麻煩,先查後遍歷修改再保存 Model.find().each().save()
Person.find({ surname: "Doe" }).each(function (person) { person.surname = "Dean"; }).save(function (err) { // done! });
Model.find().count()
Person.find({ surname: "Doe" }).count(function (err, people) { // people = number of people with surname="Doe" });
Model.Exists([ conditions, ] cb)
Person.exists({ surname: "Doe" }, function (err, exists) { console.log("We %s Does in our db", exists ? "have" : "don't have"); });
Model.aggregate
Person.aggregate({ surname: "Doe" }).min("age").max("age").get(function (err, min, max) { console.log("The youngest Doe guy has %d years, while the oldest is %d", min, max); }); //The same as "select avg(weight), age from person where country='someCountry' group by age;" Person.aggregate(["age"], { country: "someCountry" }).avg("weight").groupBy("age").get(function (err, stats) { // stats is an Array, each item should have 'age' and 'avg_weight' });
官方給出這幾個函數:min、max、avg、sum、count
groupBy只能在Model.aggregate中使用
hasOne()、hasMany(),很遺憾,限制太多(具體哪些,本身去踩坑吧)俺不搞!
db.driver.execQuery
Sequelize也接觸過一點點,不過感受沒ORM2上手那麼容易,並且感受ORM2的坑比較少 哈哈。
因爲比較菜,各位在看本人本身封裝的代碼時吐槽時嘴下留情。 但願也能給本人多些建議,tks~