1. 程式人生 > >nodejs+mongoose簡單關聯+增刪改查

nodejs+mongoose簡單關聯+增刪改查

本篇文章是關於mongoose的簡單操作,包括使用objectId來關聯和一些增刪查改的方法。希望能指出不正確的地方,因為我也是初學者。也希望能對其他初學者有幫助!謝謝!微笑微笑

node.js目錄結構:

routes:路由分發

controller:mvc中C層,做邏輯處理

models:mvc中m層,資料表模型

DBsql:模型sql操作

DBhelper:公共sql方法

資料表結構

user:學生表

schoolClass:班級表

user_schoolClass:多對多中間表


邏輯過程:

(1)新建對應表模型及關聯

(2)設計增刪改查語句

(3)邏輯層使用模型去執行增刪查改方法

(1)新建對應表模型及關聯


user模型

var mongoose = require('mongoose');
var Schema   = mongoose.Schema;

//schema 就是如何定義資料的結構
var userSchema = new mongoose.Schema({
    userName:{type:String}
});
//生成方法getModel給予呼叫,返回user模型
module.exports = {
    getModel: function(){
        return _getModel();
    }
};

//通過db將表user和Schema結構連線在一起,沒有表的話會自動產生。
var _getModel = function(type,err){
    var userModel = global.db.model('user',userSchema);
    return userModel;

};
schoolClass模型
var mongoose = require('mongoose');
var Schema   = mongoose.Schema;


var schoolClassSchema = new mongoose.Schema({
    schoolClassName:{type:String}

});
module.exports = {
    getModel: function(){
        return _getModel();
    }
};

var _getModel = function(){
    var schoolClassModel = global.db.model('schoolClass',schoolClassSchema);
    return schoolClassModel;

};
user_schoolClass模型
var mongoose = require('mongoose');
var Schema   = mongoose.Schema;

var user_schoolClassSchema = new mongoose.Schema({
    userId:{type: Schema.Types.ObjectId, ref: 'user' },//定義型別為objectid ,ref是關聯的模型名稱
    schoolClassId:{type: Schema.Types.ObjectId, ref: 'schoolClass' }<span style="font-family: Arial, Helvetica, sans-serif;">//定義型別為objectid ,ref是關聯的模型名稱</span>

});
module.exports = {
    getModel: function(){
        return _getModel();
    }
};

var _getModel = function(type,err){
    var user_schoolClassModel = global.db.model('user_schoolClass',user_schoolClassSchema);
    return user_schoolClassModel;

};
(2)設計增刪改查語句

dbHelper.js

/**
 * 公共Add方法
 * @param model 要操作資料庫的模型
 * @param conditions 增加的條件,如{id:xxx}
 * @param callback 回撥方法
 */
exports.addData =function(model,conditions,callback) {

    model.create(conditions, function(err,result){
        if(err) {
            console.log(err);
            callback({success:0,flag:"save data fail"});
        } else {

            console.log('save success');
            callback({success:1,flag:"save data success"});
        }
    });

}

/**
 * 公共update方法
 * @param model 要操作資料庫的模型
 * @param conditions 增加的條件,如{id:xxx}
 * @param update 更新條件{set{id:xxx}}
 * @param options 
 * @param callback
 */
exports.updateData =function(model,conditions,update,options,callback) {

    model.update(conditions, update, options, function(error,result){
        if(error) {
            console.log(error);
            callback({success:0,flag:"update data fail"});
        } else {
            if(result.n!=0){
                console.log('update success!');
                callback({success:1,flag:"update data success"});
            }
            else{
                console.log('update fail:no this data!');
                callback({success:0, flag: 'update fail:no this data!'});
            }

        }
    });
}

/**
 * 公共remove方法
 * @param model
 * @param conditions
 * @param callback
 */
exports.removeData =function(model,conditions,callback) {

    model.remove(conditions, function(error,result) {
        if (error) {
            console.log(error);
            callback({success: 0, flag: "remove data fail"});
        } else {
            if(result.result.n!=0){
                console.log('remove success!');
                callback({success: 1, flag: "remove data success"});
            }
            else{
                console.log('remove fail:no this data!');
                callback({success:0, flag: 'remove fail:no this data!'});
            }

        }
    });
}

/**
 * 公共find方法 非關聯查詢
 * @param model
 * @param conditions
 * @param fields 查詢時限定的條件,如順序,某些欄位不查詢等
 * @param options
 * @param callback
 */
exports.findData =function(model,conditions,fields,options,callback) {

    model.find(conditions, fields, options, function(error, result){
        if(error) {
            console.log(error);
            callback({success: 0, flag: "find data fail"});
        } else {
            if(result.length!=0){
                console.log('find success!');
                callback({success: 1, flag: "find data success",result:result});
            }
            else{
                console.log('find fail:no this data!');
                callback({success: 0, flag: 'find fail:no this data!'});
            }

        }

    });
}

/**
 * 公共populate find方法
 * 是關聯查詢
 * @param model
 * @param conditions
 * @param path :The field need to be refilled (需要覆蓋的欄位)
 * @param fields :select fields (name -_id,Separated by a space field,In front of the field name plus "-"said not filled in)
 * @param refmodel (關聯的欄位,有path可為null)
 * @param options
 * @param callback
 */
exports.findDataPopulation =function(model,conditions,path,fields,refmodel,options,callback) {
    model.find(conditions)
    .populate(path,fields, refmodel,options)
    .exec(function(err, result) {
            if(err) {
                console.log(err);
                callback({success: 0, flag: 'population find data fail'});
            } else {
                if(result.length!=0){
                    console.log('population find success!');
                    callback({success: 1, flag: 'population find data success',result:result});
                }
                else{
                    console.log('population find fail:no this data!');
                    callback({success: 0, flag: 'population find fail:no this data!'});
                }

            }

    });

}

userDao(schoolClassDao跟userDao一樣,只是獲取model是獲取schoolClass的model就不貼出來了)
var user =require('../models/user');

/**
 * 呼叫公共add方法並且傳入操作資料庫的模型user
 * @returns {Function}
 */
exports.addUser = function(conditions,dbHelper,callback) {

    //獲取user模型
    var userModel =user.getModel();
    dbHelper.addData(userModel,conditions,function(result) {
        callback(result);

    });

};
/**
 * 呼叫公共find方法並且傳入操作資料庫的模型user
 * @param conditions
 * @param dbHelper
 * @param callback
 */
exports.findUser = function(conditions,dbHelper,callback) {

    var userModel =user.getModel();
    var fields   = {};
    var options  = {};

    dbHelper.findData(userModel,conditions,fields,options,function(result){
        callback(result);
    });

}

/**
 * 呼叫公共remove方法並且傳入操作資料庫的模型user
 * @param conditions
 * @param dbHelper
 * @param callback
 */
exports.removeUser = function(conditions,dbHelper,callback) {


    var userModel =user.getModel();
    dbHelper.removeData(userModel,conditions,function(result){
        callback(result);
    });
}

/**
 * 呼叫公共update方法並且傳入操作資料庫的模型user
 * @param conditions
 * @param update
 * @param options
 * @param dbHelper
 * @param callback
 */
exports.updateUser = function(conditions,update,options,dbHelper,callback) {


    var userModel =user.getModel();
    dbHelper.updateData(userModel,conditions,update,options,function(result){
        callback(result);
    });
}

user_schoolClassDao
var user_schoolClass =require('../models/user_schoolClass');
var user = require('../models/user');
var schoolClass = require('../models/schoolClass');

/**
 * add User_schoolClass
 * @param conditions
 * @param dbHelper
 * @param callback
 */
exports.addUser_schoolClass = function(conditions,dbHelper,callback) {


    var user_schoolClassModel =user_schoolClass.getModel();

    dbHelper.addData(user_schoolClassModel,conditions,function(result) {
        callback(result);

    });


}
/**
 * find User_SchoolClass 非Ref
 * @param conditions
 * @param dbHelper
 * @param callback
 */
exports.findUser_schoolClass = function(conditions,dbHelper,callback) {

    var user_schoolClassModel =user_schoolClass.getModel();
    var conditions =conditions;
    var fields   = {};
    var options  = {};
    dbHelper.findData(user_schoolClassModel,conditions,fields,options,function(result){
        callback(result);
    });

}

/**
 * find User_SchoolClass 是Ref
 * @param conditions
 * @param path         需要被填充的欄位
 * @param dbHelper
 * @param callback
 */
exports.findUser_schoolClassRef = function(conditions,path,dbHelper,callback) {


    var user_schoolClassModel =user_schoolClass.getModel();

    var path = path;
    var fields   = {__v:0};
    var options  = {sort:{_id:1}};
    var refmodel1 = schoolClass.getModel();
    var refmodel2 = user.getModel();
    dbHelper.findDataPopulation(user_schoolClassModel,conditions,path,fields,{},options,function(result){
        callback(result);
    });


}

/**
 * remove User_shcoolClass
 * @param conditions
 * @param dbHelper
 * @param callback
 */
exports.removeUser_schoolClass = function(conditions,dbHelper,callback) {


    var user_schoolClassModel =user_schoolClass.getModel();
    dbHelper.removeData(user_schoolClassModel,conditions,function(result){
        callback(result);
    });


}

/**
 * update User_schoolClass
 * @param conditions
 * @param update
 * @param options
 * @param dbHelper
 * @param callback
 */
exports.updateUser_schoolClass = function(conditions,update,options,dbHelper,callback) {


    var user_schoolClassModel =user_schoolClass.getModel();
    dbHelper.updateData(user_schoolClassModel,conditions,update,options,function(result){
        callback(result);
    });
    
}

findUser_schoolClass :不會找出user和schoolClass的實際內容

findUser_schoolClassRef :會找出user和schoolClass的實際內容

(3)邏輯層使用模型去執行增刪查改方法

var dbHelper = require('../DBhelper/dbHelper');
var userDao =require('../DBSql/userDao');


/**
 * add user
 * @returns {Function}
 */
exports.userAddAction = function() {
    return function(req, res) {

        var user = new Array();
        for(var i=0;i<10;i++){
            user.push({
                _id   : new global.mongoose.Types.ObjectId(),
                userName  : "user"+(i+1)//欄位如果不是在model裡面定義欄位,則不會被錄入
            });
        }

        userDao.addUser(user,dbHelper,function(result){
            res.json(result);
        });
    }
}


/**
 * get User List
 * @returns {Function}
 */
exports.userFindAction = function() {
    return function(req, res) {
        var conditions ={};
        userDao.findUser(conditions,dbHelper,function(result){
            res.json(result);
        });
    }
}

exports.userRemoveAction = function() {
    return function(req, res) {
        var conditions ={};
        userDao.removeUser(conditions,dbHelper,function(result){
            res.json(result);
        });
        //除了要刪除user表裡的內容,還要刪除關聯表(user_schoolClass)的內容
    }
}

exports.userUpdateAction = function() {
    return function (req, res) {

        var conditions = {};
        var update = {}//{$set : {userName:xxx}};
        var options = {}//{upsert:false};

        userDao.updateUser(conditions, update, options, dbHelper, function (result) {
            res.json(result);
        });
        //如果要更加關聯物件,需要update user_schoolClass表中的userid 和scoolClassId
    }
}

schoolClassManagermentController跟userManagementController一樣,只有add方法有改變

var schoolClassDao =require('../DBSql/schoolClassDao');
var dbHelper = require('../DBhelper/dbHelper');

/**
 * add schoolClass
 * @returns {Function}
 */
exports.schoolClassAddAction = function() {
    return function(req, res) {

        var schoolClass =new Array();
        //新建兩個班級
        for(var i=0;i<2;i++){
            schoolClass.push({
                _id   : new global.mongoose.Types.ObjectId(),
                schoolClassName  : "class"+(i+1)
            });
        }

        //呼叫Dao的add方法來使用user模型來增加
        schoolClassDao.addSchoolClass(schoolClass,dbHelper,function(result){
            res.json(result);
        });
    }
}
①呼叫user的add方法,生成10個user。url:http://10.222.225.19:8080/userAddAction
②呼叫user的find方法檢視。url:http://10.222.225.19:8080/userFindAction
{
  "success": 1,
  "flag": "find data success",
  "result": [
    {
      "_id": "568c82c1cf41cfa50016830a",
      "userName": "user1",
      "__v": 0
    },
    {
      "_id": "568c82c1cf41cfa50016830b",
      "userName": "user2",
      "__v": 0
    },
    {
      "_id": "568c82c1cf41cfa50016830c",
      "userName": "user3",
      "__v": 0
    },
    {
      "_id": "568c82c1cf41cfa50016830d",
      "userName": "user4",
      "__v": 0
    },
    {
      "_id": "568c82c1cf41cfa50016830e",
      "userName": "user5",
      "__v": 0
    },
    {
      "_id": "568c82c1cf41cfa50016830f",
      "userName": "user6",
      "__v": 0
    },
    {
      "_id": "568c82c1cf41cfa500168310",
      "userName": "user7",
      "__v": 0
    },
    {
      "_id": "568c82c1cf41cfa500168311",
      "userName": "user8",
      "__v": 0
    },
    {
      "_id": "568c82c1cf41cfa500168312",
      "userName": "user9",
      "__v": 0
    },
    {
      "_id": "568c82c1cf41cfa500168313",
      "userName": "user10",
      "__v": 0
    }
  ]
}
③呼叫schoolClass的add方法,生成2個schoolClass。url:http://10.222.225.19:8080/schoolClassAddAction
④呼叫schoolClass的find方法檢視。url:http://10.222.225.19:8080/schoolClassFindAction
{
  "success": 1,
  "flag": "find data success",
  "result": [
    {
      "_id": "568c834c0de1c69ceb235edd",
      "schoolClassName": "class1",
      "__v": 0
    },
    {
      "_id": "568c834c0de1c69ceb235ede",
      "schoolClassName": "class2",
      "__v": 0
    }
  ]
}

user_schoolClassController除了add方法和find方法不一樣,其餘大致相同。

var schoolClassDao =require('../DBSql/schoolClassDao');
var dbHelper = require('../DBhelper/dbHelper');
var userDao =require('../DBSql/userDao');
var user_schoolClassDao =require('../DBSql/user_schoolClassDao');


/**
 * add user_schoolClass
 * @returns {Function}
 */
exports.user_schoolClassAddAction = function() {
    return function(req, res) {
        
        var userId = new Array();
        var schoolClassId = new Array();
        //查詢存在的所以user
        userDao.findUser({},dbHelper,function(result){
           if(result.success==1){
               var user =result.result;
                
               //把每個user的id取出放進陣列userId
               for(var i=0;i<user.length;i++){
                   userId[i]=user[i]._id;
               }
               
               //以相同做法將schoolClass的id取出放在schoolClassId中
               schoolClassDao.findSchoolClass({},dbHelper,function(result){
                   if(result.success==1){
                       var schoolClass =result.result;

                       for(var i=0;i<schoolClass.length;i++){
                           schoolClassId[i]=schoolClass[i]._id;
                       }

                      
                       var user_schoolClass = new Array();
                       for(var i=0;i<schoolClassId.length;i++){
                           //將前5個user與schoolclass1關聯
                           if(i==0){
                               for(var j=0;j<5;j++){
                                   user_schoolClass.push({
                                       userId:userId[i],
                                       schoolClassId:schoolClassId[i]
                                   });
                               }
                           }
                           else{
                               //將後5個user與schoolclass2關聯
                               for(var j=5;j<10;j++){
                                   user_schoolClass.push({
                                       userId:userId[i],
                                       schoolClassId:schoolClassId[i]
                                   });
                               }
                           }
                       }
                       
                       //中間表將增加user與schoolclass關聯
                       user_schoolClassDao.addUser_schoolClass(user_schoolClass,dbHelper,function(result){

                           res.json(result);
                       });

                   }
               });


           }
        });

    }
}


/**
 * 查詢方法,不關聯查詢
 * user_schoolClass find
 * @returns {Function}
 */
exports.user_schoolClassFindAction = function() {
    return function(req, res) {

        var conditions ={};
        user_schoolClassDao.findUser_schoolClass(conditions,dbHelper,function(result){
            res.json(result);

        });
    }
}

/**
 * 關聯查詢
 * user_schoolClass find Ref
 * @returns {Function}
 */
exports.user_schoolClassFindRefAction = function() {
    return function(req, res) {

        var conditions ={};
        //用空格隔開要被填充的欄位
        var path="userId schoolClassId"
        user_schoolClassDao.findUser_schoolClassRef(conditions,path,dbHelper,function(result){
            res.json(result);

        });
    }
}
⑤呼叫user_schoolClass的add方法,生成2個schoolClass。url:http://10.222.225.19:8080/user_schoolClassAddAction
⑥呼叫user_schoolClass的不關聯的find方法檢視。http://10.222.225.19:8080/user_schoolClassFindAction
{
  "success": 1,
  "flag": "find data success",
  "result": [
    {
      "_id": "568c85b19f4a4e210f07b126",
      "userId": "568c82c1cf41cfa50016830a",
      "schoolClassId": "568c834c0de1c69ceb235edd",
      "__v": 0
    },
    {
      "_id": "568c85b19f4a4e210f07b129",
      "userId": "568c82c1cf41cfa50016830a",
      "schoolClassId": "568c834c0de1c69ceb235edd",
      "__v": 0
    },
    {
      "_id": "568c85b19f4a4e210f07b12a",
      "userId": "568c82c1cf41cfa50016830a",
      "schoolClassId": "568c834c0de1c69ceb235edd",
      "__v": 0
    },
    {
      "_id": "568c85b19f4a4e210f07b128",
      "userId": "568c82c1cf41cfa50016830a",
      "schoolClassId": "568c834c0de1c69ceb235edd",
      "__v": 0
    },
    {
      "_id": "568c85b19f4a4e210f07b127",
      "userId": "568c82c1cf41cfa50016830a",
      "schoolClassId": "568c834c0de1c69ceb235edd",
      "__v": 0
    },
    {
      "_id": "568c85b19f4a4e210f07b12e",
      "userId": "568c82c1cf41cfa50016830b",
      "schoolClassId": "568c834c0de1c69ceb235ede",
      "__v": 0
    },
    {
      "_id": "568c85b19f4a4e210f07b12d",
      "userId": "568c82c1cf41cfa50016830b",
      "schoolClassId": "568c834c0de1c69ceb235ede",
      "__v": 0
    },
    {
      "_id": "568c85b19f4a4e210f07b12c",
      "userId": "568c82c1cf41cfa50016830b",
      "schoolClassId": "568c834c0de1c69ceb235ede",
      "__v": 0
    },
    {
      "_id": "568c85b19f4a4e210f07b12f",
      "userId": "568c82c1cf41cfa50016830b",
      "schoolClassId": "568c834c0de1c69ceb235ede",
      "__v": 0
    },
    {
      "_id": "568c85b19f4a4e210f07b12b",
      "userId": "568c82c1cf41cfa50016830b",
      "schoolClassId": "568c834c0de1c69ceb235ede",
      "__v": 0
    }
  ]
}
可以看出並沒有顯示user 和schoolClass相關資料,只顯示了id;
⑦呼叫user_schoolClass的關聯的find方法檢視。http://10.222.225.19:8080/user_schoolClassFindRefAction
{
  "success": 1,
  "flag": "population find data success",
  "result": [
    {
      "_id": "568c85b19f4a4e210f07b126",
      "userId": {
        "_id": "568c82c1cf41cfa50016830a",
        "userName": "user1"
      },
      "schoolClassId": {
        "_id": "568c834c0de1c69ceb235edd",
        "schoolClassName": "class1"
      },
      "__v": 0
    },
    {
      "_id": "568c85b19f4a4e210f07b129",
      "userId": {
        "_id": "568c82c1cf41cfa50016830a",
        "userName": "user1"
      },
      "schoolClassId": {
        "_id": "568c834c0de1c69ceb235edd",
        "schoolClassName": "class1"
      },
      "__v": 0
    },
    {
      "_id": "568c85b19f4a4e210f07b12a",
      "userId": {
        "_id": "568c82c1cf41cfa50016830a",
        "userName": "user1"
      },
      "schoolClassId": {
        "_id": "568c834c0de1c69ceb235edd",
        "schoolClassName": "class1"
      },
      "__v": 0
    },
    {
      "_id": "568c85b19f4a4e210f07b128",
      "userId": {
        "_id": "568c82c1cf41cfa50016830a",
        "userName": "user1"
      },
      "schoolClassId": {
        "_id": "568c834c0de1c69ceb235edd",
        "schoolClassName": "class1"
      },
      "__v": 0
    },
    {
      "_id": "568c85b19f4a4e210f07b127",
      "userId": {
        "_id": "568c82c1cf41cfa50016830a",
        "userName": "user1"
      },
      "schoolClassId": {
        "_id": "568c834c0de1c69ceb235edd",
        "schoolClassName": "class1"
      },
      "__v": 0
    },
    {
      "_id": "568c85b19f4a4e210f07b12e",
      "userId": {
        "_id": "568c82c1cf41cfa50016830b",
        "userName": "user2"
      },
      "schoolClassId": {
        "_id": "568c834c0de1c69ceb235ede",
        "schoolClassName": "class2"
      },
      "__v": 0
    },
    {
      "_id": "568c85b19f4a4e210f07b12d",
      "userId": {
        "_id": "568c82c1cf41cfa50016830b",
        "userName": "user2"
      },
      "schoolClassId": {
        "_id": "568c834c0de1c69ceb235ede",
        "schoolClassName": "class2"
      },
      "__v": 0
    },
    {
      "_id": "568c85b19f4a4e210f07b12c",
      "userId": {
        "_id": "568c82c1cf41cfa50016830b",
        "userName": "user2"
      },
      "schoolClassId": {
        "_id": "568c834c0de1c69ceb235ede",
        "schoolClassName": "class2"
      },
      "__v": 0
    },
    {
      "_id": "568c85b19f4a4e210f07b12f",
      "userId": {
        "_id": "568c82c1cf41cfa50016830b",
        "userName": "user2"
      },
      "schoolClassId": {
        "_id": "568c834c0de1c69ceb235ede",
        "schoolClassName": "class2"
      },
      "__v": 0
    },
    {
      "_id": "568c85b19f4a4e210f07b12b",
      "userId": {
        "_id": "568c82c1cf41cfa50016830b",
        "userName": "user2"
      },
      "schoolClassId": {
        "_id": "568c834c0de1c69ceb235ede",
        "schoolClassName": "class2"
      },
      "__v": 0
    }
  ]
}
PS:ip地址需要自己修改
可以通過"."(點)方法取出資料,取出userName方法result.userId.userName
參考文章:
資源下載: