儲存過程
關係型資料庫的儲存過程描述為: 一組為了完成特定功能的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命令執行儲存過程。