mongo 儲存過程詳解

你笑的像一條狗發表於2018-12-15

儲存過程

關係型資料庫的儲存過程描述為: 一組為了完成特定功能的SQL 語句集,經編譯後儲存在資料庫中,使用者通過指定儲存過程的名字並給出引數(如果該儲存過程帶有引數)來執行它 。

MongoDB 為很多問題提供了一系列的解決方案,針對於其它資料庫的特性,它仍然毫不示 弱,表現的非比尋常。MongoDB 同樣支援儲存過程,但mongoDB是用javascript來寫的 ,這正是mongoDB的魅力。

MongoDB 同樣支援儲存過程。關於儲存過程你需要知道的第一件事就是它是用 javascript 來寫的。也許這會讓你很奇怪,為什麼它用 javascript 來寫,但實際上它會讓你非常滿意,MongoDB 儲存過程是儲存在 db.system.js 表中的

例如:

計算x+y的值

function test(x,y){

return x+y;
}
複製程式碼

定義查詢總數 儲存過程

function findTotal(){
return db.user.find().count();
}
複製程式碼

編譯儲存

db.system.js.save({"_id":"test","value":function test(x,y){return x+y;}});
複製程式碼
db.system.js.save({"_id":"findTotal","value":function findTotal(){return db.user.find().count();})
複製程式碼

執行返回

// 1
WriteResult({
	"nMatched" : 1,
	"nUpserted" : 0,
	"nModified" : 0,
	"writeConcernError" : [ ]
})
複製程式碼

eval 函式

可以將儲存過程邏輯直接在裡面定義並且 同時呼叫,無需事先宣告!

db.eval("function test(x,y){return 2 + 4;}");  // 6 
複製程式碼
查詢表中的資料總數
db.eval("function total(){ return db.user.find().count();}");  //25
複製程式碼

檢視所有的儲存過程

db.system.js.find();

在這裡插入圖片描述

執行結果

總數

db.eval('findTotal()');

在這裡插入圖片描述

db.eval('test(2,4)');

在這裡插入圖片描述

mongodb 執行儲存過程

mongodb 儲存過程是用js語言寫的,java呼叫js指令碼即可!

java 執行js指令碼檔案:

/**
 * 呼叫mongodb儲存過程 js指令碼檔案
 * @return
 */
@Test
public void test(){
    ScriptOperations scriptOps = mongoTemplate.scriptOps();
    Object findTotal = scriptOps.call("findTotal");//執行伺服器端指令碼
    //call(String script,Object...args)引數放在指令碼名稱之後
    Object test = scriptOps.call("test",4,4);//執行伺服器端指令碼

    System.out.println(Double.parseDouble(findTotal.toString()));  //25條
    System.out.println(Double.parseDouble(test.toString()));       // 8 
 
}
複製程式碼

注意script指令碼不能為null或者“” 不然會異常!

mongoTemplate 中方法返回DefaultScriptOperations物件:

MongoTemplate 實現 MongoOperations介面

MongoTemplate 中方法

public ScriptOperations scriptOps() {
    return new DefaultScriptOperations(this);
}
複製程式碼
call方法

介面 ScriptOperations

@Nullable
Object call(String var1, Object... var2);
複製程式碼

實現類:

class DefaultScriptOperations 實現ScriptOperations 介面

構造方法

public DefaultScriptOperations(MongoOperations mongoOperations) {
    Assert.notNull(mongoOperations, "MongoOperations must not be null!");
    this.mongoOperations = mongoOperations;
}
複製程式碼

方法

public Object call(final String scriptName, final Object... args) {
    Assert.hasText(scriptName, "ScriptName must not be null or empty!");
    return this.mongoOperations.execute(new DbCallback<Object>() {
        public Object doInDB(MongoDatabase db) throws MongoException, DataAccessException {
            return db.runCommand(new Document("eval", String.format("%s(%s)", scriptName, DefaultScriptOperations.this.convertAndJoinScriptArgs(args)))).get("retval");
        }
    });
}
複製程式碼

通過呼叫scriptOps()方法返回MongoOperations引用 ,實際上還是mongoTemplate去執行execute方法 是在 ScriptOperations介面的實現類中DefaultScriptOperations 呼叫 ScriptOperations介面的call方法,最後根據DefaultScriptOperations 類中的去其他方法 convertAndJoinScriptArgs 傳遞驗證引數型別以及轉換。 最後呼叫最底層runCommand命令執行儲存過程。

相關文章