同步操作将从 drinkjava2/MyServerless 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
天下武功,唯快不破,程序无非就是接收用户输入、存到数据库。GoSqlGo能让前端直接存取数据库,独立完成项目开发。
一直认为,开发效率最高的方式不是让MVC架构极简(SpringBoot/jFinal),而是彻底省略掉MVC架构和后端程序员,直接由前端搞定一切,由多层架构变成两层,在前端直接写SQL,缩短输入和SQL的矩离,才是最快的开发途径。基于此理念,在2011年本人在这里写了一句预言,没想到技术的发展如此之慢,现在要自己亲手去实现它了,这就是GoSqlGo项目,如果名字翻译成中文,可以翻成"Sql冲冲冲冲冲",这个比较形象,它表达了SQL为王,一路狂奔,冲到了前端的意思。
GoSqlGo是一个运行于后端的开发工具,它的最大特点就是在开发期动态编译客户端Java代码,所有SQL和Java代码都可以在前端Html页面完成,可以彻底甩掉后端了。开发完成后利用打包工具再将SQL和Java从前端移到后端。
忘掉MVC吧,因为现在架构变成MV两层了;忘掉FreeMaker之类模板吧,因为Java本身变成了Javascript中的模板语言。忘掉后端程序员吧,因为后端除了写数据库,本来就没多少事干,现在这点活也由前端接管了。忘掉前端校验吧,因为后端校验这活也归前端了,前端校验能偷懒就偷吧。
前端程序员可以直接在Javascript里写SQL和Java代码,例如以下为一个HTML片段,实测通过,完整文件位于这里。
这是一个转账业务的演示,它把所有的业务逻辑都写在html里面,不再需要和后端程序员沟通了:
<!DOCTYPE html>
<html>
<head>
<script src="/js/jquery-1.11.3.min.js"></script>
<script src="/js/jquery-ajax-ext.js"></script>
<script src="/js/gosqlgo.js"></script>
</head>
<body>
<h1>Transaction Demo</h1>
<div id="msgid" class="msg"></div>
<section>
<header>Account A</header>
<div id="A" class="amount">
<script>
document.write($qry('select amount from account where id=? and amount>=?', 'A',0));
</script>
</div>
</section>
<section>
<header>Account B</header>
<div id="B" class="amount">
<script>
document.write($qry('select amount from account where id=? and amount>=?', 'B',0));
</script>
</div>
</section>
<script>
function transfer(from, to, money){
var rst = $java(`TX
int money=Integer.parseInt($3);
if(money<=0)
throw new SecurityException("Money<=0, IP:"+ getRequest().getRemoteAddr());
Account a=new Account().setId($1).load();
if(a.getAmount()<money)
return "No enough balance!";
Account b=new Account().setId($2).load();
a.setAmount(a.getAmount()-money).update();
b.setAmount(b.getAmount()+money).update();
return "Transfer Success!|"+a.getAmount()+"|"+b.getAmount();
`, from,to,money
);
if(rst.startsWith("Transfer Success!")) {
var words=rst.split('|');
$("#msgid").text(words[0]);
$("#"+from).text(words[1]);
$("#"+to).text(words[2]);
$("#msgid").css("background", "#dfb");
}
else { $("#msgid").text(rst);
$("#msgid").css("background", "#ffbeb8");
}
}
</script>
<section>
<header>Transfer</header>
<form onsubmit="return false" action="##" method="post">
<input name="amount" value="100" class="amount">
<button name="btnA2B" value="true" onclick="transfer('A','B',100)">From
account A to account B</button>
<button name="btnB2A" value="true" onclick="transfer('B','A',100)">From
account B to account A</button>
</form>
</section>
</body>
</html>
GoSqlGo运行在服务端,只需要进行简单的数据源设定、ActiveRecord实体类定义就可以了,详见demo/gsg-tomcat/src/main/java/com/gitee/gosqlgo/demo/InitConfig.java文件内容。
GoSqlGo在客户端只需要添加一个gosqlgo.js,就可以进行服务端调用了,所有业务写在客户端。gosqlgo.js只有2个方法:
开发阶段:GoSqlGo在服务端运行,它自带一个动态编译工具,前端发来的SQL和Java片段,被运态编译为Java类,并调用其自带的ORM工具(采用jSqlBox),运行并返回文本或JSON对象。
在Sql/Java片段里面,返回值可以分为以下类型,但客户端最终收到的都是一个字符串:
布署阶段:通过一个打包工具,将前端所有的SQL和原生Java片段打包到服务端去,静态存为可调试的Java源文件,原有客户端的SQl和JAVA代码在打包后将成为类似于qry('C9GK90J27','A');之类的通过ID进行的调用,以实现安全性。
对于Sql/Java字符串片段,有以下可选控制字符:
TX,表示开启事务
SERV,永远留在后端,一旦用goServ命令抽取到服务端,就不能再用goFront命令塞回到前端了
FRONT, 永远留在前端,不会被抽取出来,直到使用deploy命令才会被抽取到Server端
#xxxxx形式,手工指定ID, 如果不定义ID, 则由工具随机自动生成,用goFront命令塞回到前端时会删除这个随机ID
import 开头,为标准Java的import语句
示例: qry('TX SERV #ReadAmount import abc.Demo1;import abc.Demo2; select amount from account where id=? and amount<>?', 'A',0);
GoSqlGO使用需要在项目里加入以下依赖:
<dependency>
<groupId>com.github.drinkjava2</groupId>
<artifactId>gosqlgo</artifactId>
<version>1.0.0</version>
</dependency>
它主要有两个功能:
1.动态编译客户端传来的SQL/Java,生成Java类,例如以下调用会动态地根据Java源码生成内存中的Java类:
DynamicCompileEngine.instance.javaCodeToClass(className, classSrc); 这个功能通常前端程序员不需要了解。
2.打包工具,将前端的SQL/Java抽出到后端, 有三个方法,使用示例:
new DeployTool().toServ(); //将HTML/Javascript中的sql和java代码抽取出来,生成Java类发布到项目源码的deploy目录下
//如果SQL/Java片段开头含有"FRONT"关键字打头将不抽取
new DeployTool().deploy(); //同上,但是忽略FRONT关键字,一律抽取到服务端,以实现安全性
new DeployTool().toFront(); //逆操作,将抽取出来的SQL/Java类再塞回到HTML/Javascript中
原则上GoSqlGo可以使用在任意支持JSP的Servlet容器内,并可搭配不同的DAO工具使用,但是学习它最简单的方法是运行它的示例项目"gsg-tomcat",这是个微型的服务端框架:
"gsg-tomcat"项目需Java8或以上,用git clone下载后, 有三种运行方式:
方式1,发布war包到本机的Tomcat7或Tomcat8目录下执行:
运行:修改run-normal-tomcat.bat批处理文件中的TomcatFolder为本机Tomcat目录,并执行
查看:浏览器输入 http://localhost
方式2, 命令行方式运行嵌入式Tomcat,这种方式本机不需要安装Tomcat, Maven会自动下载
运行:双击运行run-embeded-tomcat.bat批处理即可
查看:浏览器输入 http://localhost
方式3, 导入到Eclipse中运行
1.运行run-embeded-tomcat.bat批处理一次
2.运行maven_eclipse_eclipse.bat批处理,生成eclipse配置
3.打开Eclipse,导入项目,并运行其中的EmbedMain.java的main方法
查看:浏览器输入 http://localhost
另外在项目resources目录下,有一个名为GoSqlGo.properties的配置文件,可以进行一些配置,例如配置后端Java类模板等,请自行打开查看。
安全上有没有问题?
有,在java方法里,可以手工进行参数合法性检查,不存在架构上的安全漏洞,但是在qry方法里,没有进行参数校验的语句,如果遇到客户端恶意传入非法SQL参数,例如想要调入用户A的账户,却传入了用户C的账户ID,这时候就会出现非法存取,甚至出现扫表情况,整张表的信息都会泄露。
为什么有这么大的漏洞还要保留qry方法? 因为作者认为方便性要大于安全性。例如对于OSC这种社交类网站,除了用户密码外,大多数表格内容都是可以公开的,即使出现非法参数或扫表,也不是件大事。当然扫表太历害就成了DDOS攻击了,后端要加上对qry进行存取频率限制或登录检查的切面处理。
对于安全性要求高的公司,可以强制要求不允行使用qry方法。或者后端对SQL写法提出要求,如存取到的表格、字段必须用!、#等符号注明出来,并结合切面类进行安全检查。
为什么采用过时的JSP技术?
也可以不用。但作者的技术栈比较落后,采用JSP技术后,可以更简单地进行后端页面布局(jWebBox对标Apache Tiles)和模块式开发。大前端时代,后端的页面布局有时还是要用到的,它可以一次将页面渲染后发给前端,提高用户体验,防止多次AJAX调用造成的马塞克似的东一块、西一块的页面加载,尤其在网速差的情况下。
一般情况下,前端并不需要了解后端的实现技术细节,如果我不提,前端的人可能根本不知道GoSqlgo采用了JSP技术。
为什么示例项目采用jSqlBox这么小众的、没经过时间检验的DAO工具?
因为jSqlBox是作者自已写的DAO工具,打广告用的,它的DAO功能很全,号称SQL写法百科全书,目前已支持DAO层的分片,将来有可能将分布式事务、容错等技术也做在DAO层,方便前端使用。如果前端对jSqlBox不感冒,可以对公司的后端提要求,搭配不同的DAO工具即可。
GoSqlGo与其说是个产品,不如说是个概念,稍有经验的后端都可以在它的基础上开发出支持其它ORM、MVC框架的更稳定的后端平台。前端并不需要太关心后端框架技术细节,只需要关心SQL的写法和ORM工具的使用。
如果所有业务逻辑写在前端,则不管后端采用什么框架,前端的写法基本不变,例如SQl的写法和ActiveRecord的写法,所有ORM工具都大同小异。
(小鹏提出)Java写在HTML/Javascript里没有错误检查、语法提示
这个将来可以通过IDE插件解决,但目前只能用goServ方法将Sql/Java抽取成Java源码类,在IDE里找错、更正后再用goFront方法塞回到HTML里去,也可以干脆就不塞回去了,后者就对应传统的前后端分离开发情形。
GoSqlGo第一版已正式发布,对它感兴趣的请加关注,或发issue提出更好的意见,帮助完善它。也欢迎加入GoSqlGo开发组。
点赞很重要,必须的
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。