orm2

數據庫鏈接

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定義

官方的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!
});

 

取COUNT

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(),很遺憾,限制太多(具體哪些,本身去踩坑吧)俺不搞!

 

多表查詢替代方法 && 直接執行SQL

db.driver.execQuery

按 Ctrl+C 複製代碼
按 Ctrl+C 複製代碼

 

Sequelize也接觸過一點點,不過感受沒ORM2上手那麼容易,並且感受ORM2的坑比較少 哈哈。

因爲比較菜,各位在看本人本身封裝的代碼時吐槽時嘴下留情。 但願也能給本人多些建議,tks~

相關文章
相關標籤/搜索