关系型数据库的存储过程描述为: 一组为了完成特定功能的SQL 语句集,经编译后存储在数据库中,用户经过指定存储过程的名字并给出参数(若是该存储过程带有参数)来执行它 。javascript
MongoDB 为不少问题提供了一系列的解决方案,针对于其它数据库的特性,它仍然绝不示 弱,表现的非比寻常。MongoDB 一样支持存储过程,但mongoDB是用javascript来写的 ,这正是mongoDB的魅力。java
MongoDB 一样支持存储过程。关于存储过程你须要知道的第一件事就是它是用 javascript 来写的。也许这会让你很奇怪,为何它用 javascript 来写,但实际上它会让你很是满意,MongoDB 存储过程是存储在 db.system.js 表中的mongodb
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" : [ ]
})
复制代码
能够将存储过程逻辑直接在里面定义而且 同时调用,无需事先声明!数据库
db.eval("function test(x,y){return 2 + 4;}"); // 6
复制代码
db.eval("function total(){ return db.user.find().count();}"); //25
复制代码
db.system.js.find();json
总数bash
db.eval('findTotal()');服务器
db.eval('test(2,4)');函数
mongodb 存储过程是用js语言写的,java调用js脚本便可!ui
/** * 调用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或者“” 否则会异常!this
mongoTemplate 中方法返回DefaultScriptOperations对象:
MongoTemplate 实现 MongoOperations接口
MongoTemplate 中方法
public ScriptOperations scriptOps() {
return new DefaultScriptOperations(this);
}
复制代码
接口 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命令执行存储过程。