Jfinal试用报告
2015-05-02 10:40
169 查看
前言
为了解决现有的开发框架配置繁琐,开发效率不高的问题。同时能适应简单业务快速开发的功能,适应多样化需求的变动减少开发人员繁琐、重复的劳动,专注于业务实现。通过讨论认为jFinal比较合适,于是乎试用了一把。本文结合网络咨料和自己的使用心得整理而成,欢迎有兴趣的同学一起探讨学习,推动开源框架向前发展。我的微信公众号见最下面的图。
为了便于sql集中管理,已有的框架也有,但个人不喜欢把sql放到xml里,于是自己写了个sqldb插件,sql放在properties里,有相同想法的同学可以试用一下,源码地址:https://git.oschina.net/wxt/jfinal-dbplugs.git
框架简介
JFinal是一款基于Java语言的开源Web开发框架,其核心设计目标是开发迅速、代码量少、学习简单、功能强大、轻量级、易扩展、Restful风格。在拥有Java语言所有优势的同时再拥有Ruby、Python等动态语言的开发效率。使用它不但能实现多个开发框架的功能,效率方面也有极大的提升。
框架特点
MVC架构,设计精巧,使用简单
遵循COC原则,零配置,无xml
独创Db + Record模式,灵活便利
ActiveRecord支持,使数据库开发极致快速
AOP支持,拦截器配置灵活,功能强大
Plugin体系结构,扩展性强
多视图支持,支持FreeMarker、JSP、Velocity
强大的Validator后端校验功能
功能齐全,拥有struts2的绝大部分功能
体积小仅248K,且无第三方依赖
自动加载修改后的java文件,开发过程中无需重启web server
架构组成
JFinal框架由Handler、Interceptor、Controller、Render、validator和Plugin五大部分组成。每个部分都基于接口实现,支持完整的自定义,扩展性强,使用灵活,设计精巧且使用简单。JFinal的逻辑架构采用经典的MVC架构,其中包括httpServletRequest(客户端请求)、HttpServletResponse(客户端响应)、所有请求的拦截器、请求处理器(对所有请求的公共处理)、动作处理器(它是一个AOP+Command模式变种,由ActionInvocation进行调度,先执行拦截器,最后执行具体方法),这样的逻辑架构使得系统层次分明,便于开发人员理解和使用。
数据持久层以plugin方式提供ActiveRecord插件,ActiveRecord 是 JFinal 最核心的组成部分之一,通过 ActiveRecord 来操作数据库, 将极大地减少代码量,极大地提升开发效率。同时数据持久层可以使用Db + Record 模式,Db 类及其配套的Record 类,提供了在 Model 类之外更为丰富的数据库操作功能。使用Db 与 Record 类时,无需对数据库表进行映射。 Record 相当于一个通用的 Model,适用于快速开发。
总体的架构图如图1。
![](http://static.oschina.net/uploads/space/2015/0429/132430_YnIK_1380141.jpg)
hander使用场景
配置全局参数
过滤某些不需要进入的URL,例如静态文件
记录耗时
cookie、请求参数的处理
国际化处理
设置请求头消息
interceptor使用场景
权限控制
设置属性
全局异常处理
访问统计
session处理
使用体验
路由默认规则
url 组成访问目标
localhost:8080/controllerKey
调用YourController.index()
localhost:8080/controllerKey/method
调用YourController.method()
localhost:8080/controllerKey/method/v0-v1
调用YourController.method(),所带 url 参数值为:v0-v1
localhost:8080/controllerKey/v0-v1
调用YourController.index(),所带 url 参数值为:v0-v1
页面数据校验
@Before(BlogValidator.class)
public void save() {
Blog me=getModel(Blog.class);
me.set("id", 2);
me.save();
redirect("/blog");
}
校验使用AOP拦截器实现。
页面数据处理
数据获取调用框架的getModel,将resquest中的数据自动映射到Blog类中;也可以在Controller中直接获取数据,getPara(“id”);
持久层配置
单数据源配置
持久层使用ActiveRecord,以下是 Plugin 配置示例代码
C3p0Plugin cp = new C3p0Plugin("jdbc:mysql://localhost/db_name",
"userName", "password");
me.add(cp);
ActiveRecordPlugin arp = new ActiveRecordPlugin(cp);
me.add(arp);
arp.addMapping("user", User.class);
arp.addMapping("article", "article_id", Article.class);
以上代码配置了两个插件:C3p0Plugin 与 ActiveRecordPlugin,前者是 c3p0 数据源插件,ActiveReceord 中定义了 addMapping(String tableName, Class<? extends Model> modelClass>)方法,该方法建立了数据库表名到 Model 的映射关系。
User类定义如下:
public class User extends Model<User> {
public static final User dao = new User();
}
User类中无须定义属性,框架启动时会从数据库中把对应表“user”中的字段通过反射机制实例化到user中,通过user. getStr(String attr)获取从数据库中查询的数据,若数据库字段名有变动加别名解决应用需要同步修改的问题。
多数据源配置
// 配置Druid 数据库连接池插件
DruidPlugin dbPlugin = new DruidPlugin(getProperty("jdbcUrl"), getProperty("user"), getProperty("password") );
me.add(dbPlugin);
// 配置ActiveRecord插件
ActiveRecordPlugin arp = new ActiveRecordPlugin("mysql", dbPlugin);
me.add(arp);
// h2数据库
JdbcConnectionPool cpH2 = JdbcConnectionPool.create(MonitorConfig.dbUrl, MonitorConfig.dbUserName, MonitorConfig.dbPassword);
ActiveRecordPlugin arpH2 = new ActiveRecordPlugin("h2", cpH2);
me.add(arpH2);
arpH2.addMapping("blog", Blog.class); // 映射blog 表到 Blog模型
arp.addMapping("blog", Blog1.class); // 映射blog 表到 Blog模型
数据库操作
实体对应操作的数据库为ActiveRecordPlugin中配置的数据库,可以在初始化时指定不同的数据库,对应配置的代码为:arp.addMapping("user", User.class);操作的数据库对arp配置的数据库。
新增
@Before(BlogValidator.class)
public void save() {
Blog me=getModel(Blog.class);
me.set("id", 2);
me.save();
redirect("/blog");
}
另一种方式
Record user = new Record().set("name", "James").set("age", 25);
Db.save("user", user);
修改
@Before(BlogValidator.class)
public void update() {
getModel(Blog.class).update();
redirect("/blog");
}
删除
public void delete() {
Blog.me.deleteById(getParaToInt());
redirect("/blog");
}
另一种方式
// 删除id值为25的user表中的记录
Db.deleteById("user", 25);
单表查询
public void query() {
setAttr("blog", Blog.me.findById(getParaToInt()));
}
另一种方式
// 查询id值为25的user, 且仅仅取name与age两个字段的
user = Db.findById("user", 25, "name, age");
复杂sql查询
public void relation() {
String sql = "select b.*, u.user_name from blog b inner
join user u on b.user_id=u.id where b.id=?";
Blog blog = Blog.dao.findFirst(sql, 123);
String name = blog.getStr("user_name");
}
说明:返回的blog属性多了name,只要不重复就不会报错,相当于blog对象是的属性是不固定的,根据查询的结果动态增加。
另一种方式查询
// 查询 dsMysql数据源中的 user
List<Record> users = Db.use("mysql").find("select * from user");
// 查询 dsOracle数据源中的 blog
List<Record> blogs = Db.use("oracle").find("select * from blog");
数据库事物
boolean succeed = Db.tx(new IAtom(){
public boolean run() throws SQLException {
int count = Db.update("update account set cash = cash - ? where
id = ?", 100, 123);
int count2 = Db.update("update account set cash = cash + ? where
id = ?", 100, 456);
return count == 1 && count2 == 1;
}});
以上两次数据库更新操作在一个事务中执行,如果执行过程中发生异常或者 invoke()方法
返回 false,则自动回滚事务。
方法2
声名式事务处理
@Before(Tx.class)
public void trans_demo() {
…
}
返回页面数据处理
render 系列方法将渲染不同类型的视图并返回给客户端。JFinal 目前支持的视图类型有:
FreeMarker、JSP、Velocity、JSON、File、Text、Html 等等。除了 JFinal 支持的视图型以外,
还可以通过继承 Render 抽象类来无限扩展视图类型。
render(String view)使用例子:
方法调用 描述
render(”test.html”) 渲染名为 test.html 的视图,该视图的 全路径为”/path/test.html”
render(”/other_path/test.html”) 渲染名为 test.html 的视图,该视图的全路径为”/other_path/test.html”,即当参数以”/”开头时将采用绝对路径
其它 render 方法使用例子:
方法调用 描述
renderFreeMarker(”test.html”) 渲染 名为 test.html 的视图 , 且 视图类 型为FreeMarker。
renderJsp(”test.html”) 渲染名为 test.html 的视图,且视图类型为 Jsp。
renderVelocity(“test.html”) 渲染名为 test.html 的视图,且视图类型为 Velocity。
renderJson()将所有通过 Controller.setAttr(String, Object)设置的变量转换成 json 数据并渲染。
renderJson(“users”, userList) 以”users”为根,仅将 userList 中的数据转换成 json数据并渲染。
renderJson(user) 将 user 对象转换成 json 数据并渲染。
http://www.jfinal.com
renderJson(“{\”age\”:18}” ) 直接渲染 json 字符串。
renderJson(new String[]{“user”, “blog”})仅将 setAttr(“user”, user)与 setAttr(“blog”, blog)设置的属性转换成 json 并渲染。使用 setAttr 设置的其它属性并不转换为 json。
renderFile(“test.zip”); 渲染名为 test.zip 的文件,一般用于文件下载
renderText(“Hello JFinal”) 渲染纯文本内容”Hello JFinal”。
renderHtml(“Hello Html”) 渲染 Html 内容”Hello Html”。
renderError (404 , “test.html”) 渲染名为 test.html 的文件,且状态为 404。
renderError (500 , “test.html”) 渲染名为 test.html 的文件,且状态为 500。
renderNull() 不渲染,即不向客户端返回数据。
render(new XmlRender())使用自定义的 XmlRender 来渲染。
结论
通过研究发现JFinal不但可以很好的代替SSH作为Java Web开发的首选框架,而且该框架的思想使java获得第二春,它改变了我们对传统java框架的认识,与Ruby、Python等动态语言的开发效率相媲美;该框架虽然为国人开发,但文档齐全,目前还有视频教学,极大降低了开发人员的学习成本,有利于新手快速入门,比起流行的SSH框架学习成本要低很高。Jfinal为开源框架,源代码非常小,可以快速地通读源码,对源码的充分理解解决了外部框架不可控的问题。
附录
官网
http://www.jfinal.com/
视频文档:
http://jfinalxm.sturgeon.mopaas.com/
jfinal-ext介绍
是对java极速web框架 jfinal 的一个扩充,主要利用jfinal微内核高扩展的特性扩展常用的实用功能和集成各种第三方框架,简化开发者的学习应用成本,引入了guava和joor包,代码更简洁。
常用的插件基本都有
其它插件介绍
cn.dreampie.jfinal-tablebind
https://github.com/Dreampie/jfinal-tablebind jfinal的table自动绑定插件,支持多数据源
cn.dreampie.jfinal-quartz
https://github.com/Dreampie/jfinal-quartz 基于jfinal 的quartz管理器
cn.dreampie.jfinal-sqlinxml
https://github.com/Dreampie/jfinal-sqlinxml 基于jfinal 的类似ibatis的sql语句管理方案
cn.dreampie.jfinal-akka
https://github.com/Dreampie/jfinal-akka java使用akka执行异步任务
cn.dreampie.jfinal-mailer
https://github.com/Dreampie/jfinal-mailer 使用akka发布邮件的jfinal插件
cn.dreampie.jfinal-slf4j
https://github.com/Dreampie/jfinal-slf4j 让jfinal使用slf4j的日志api
cn.dreampie.jfinal-lesscss
https://github.com/Dreampie/jfinal-lesscss java实现的lesscsss实时编译插件,可以由于jfinal
cn.dreampie.jfinal-shiro
https://github.com/Dreampie/jfinal-shiro 支持注解和数据库配置的shiro插件
cn.dreampie.jfinal-shiro-freemarker
https://github.com/Dreampie/jfinal-shiro-freemarker shiro插件实现的freemarker标签库
cn.dreampie.jfinal-web
https://github.com/Dreampie/jfinal-web 相关web插件,简洁model实现
cn.dreampie.jfinal-utils
https://github.com/Dreampie/jfinal-utils 部分jfinal工具
cn.dreampie.jfinal-flyway
https://github.com/Dreampie/jfinal-flyway 数据库脚本升级插件,开发中升级应用时,使用脚本同步升级数据库或者回滚
cn.dreampie.jfinal-captcha
基于jfinal render的超简单验证吗插件
cn.dreampie.jfinal-coffeescript
https://github.com/Dreampie/jfinal-coffeescript java实现的coffeescript实时编译插件
为了解决现有的开发框架配置繁琐,开发效率不高的问题。同时能适应简单业务快速开发的功能,适应多样化需求的变动减少开发人员繁琐、重复的劳动,专注于业务实现。通过讨论认为jFinal比较合适,于是乎试用了一把。本文结合网络咨料和自己的使用心得整理而成,欢迎有兴趣的同学一起探讨学习,推动开源框架向前发展。我的微信公众号见最下面的图。
为了便于sql集中管理,已有的框架也有,但个人不喜欢把sql放到xml里,于是自己写了个sqldb插件,sql放在properties里,有相同想法的同学可以试用一下,源码地址:https://git.oschina.net/wxt/jfinal-dbplugs.git
框架简介
JFinal是一款基于Java语言的开源Web开发框架,其核心设计目标是开发迅速、代码量少、学习简单、功能强大、轻量级、易扩展、Restful风格。在拥有Java语言所有优势的同时再拥有Ruby、Python等动态语言的开发效率。使用它不但能实现多个开发框架的功能,效率方面也有极大的提升。
框架特点
MVC架构,设计精巧,使用简单
遵循COC原则,零配置,无xml
独创Db + Record模式,灵活便利
ActiveRecord支持,使数据库开发极致快速
AOP支持,拦截器配置灵活,功能强大
Plugin体系结构,扩展性强
多视图支持,支持FreeMarker、JSP、Velocity
强大的Validator后端校验功能
功能齐全,拥有struts2的绝大部分功能
体积小仅248K,且无第三方依赖
自动加载修改后的java文件,开发过程中无需重启web server
架构组成
JFinal框架由Handler、Interceptor、Controller、Render、validator和Plugin五大部分组成。每个部分都基于接口实现,支持完整的自定义,扩展性强,使用灵活,设计精巧且使用简单。JFinal的逻辑架构采用经典的MVC架构,其中包括httpServletRequest(客户端请求)、HttpServletResponse(客户端响应)、所有请求的拦截器、请求处理器(对所有请求的公共处理)、动作处理器(它是一个AOP+Command模式变种,由ActionInvocation进行调度,先执行拦截器,最后执行具体方法),这样的逻辑架构使得系统层次分明,便于开发人员理解和使用。
数据持久层以plugin方式提供ActiveRecord插件,ActiveRecord 是 JFinal 最核心的组成部分之一,通过 ActiveRecord 来操作数据库, 将极大地减少代码量,极大地提升开发效率。同时数据持久层可以使用Db + Record 模式,Db 类及其配套的Record 类,提供了在 Model 类之外更为丰富的数据库操作功能。使用Db 与 Record 类时,无需对数据库表进行映射。 Record 相当于一个通用的 Model,适用于快速开发。
总体的架构图如图1。
![](http://static.oschina.net/uploads/space/2015/0429/132430_YnIK_1380141.jpg)
hander使用场景
配置全局参数
过滤某些不需要进入的URL,例如静态文件
记录耗时
cookie、请求参数的处理
国际化处理
设置请求头消息
interceptor使用场景
权限控制
设置属性
全局异常处理
访问统计
session处理
使用体验
路由默认规则
url 组成访问目标
localhost:8080/controllerKey
调用YourController.index()
localhost:8080/controllerKey/method
调用YourController.method()
localhost:8080/controllerKey/method/v0-v1
调用YourController.method(),所带 url 参数值为:v0-v1
localhost:8080/controllerKey/v0-v1
调用YourController.index(),所带 url 参数值为:v0-v1
页面数据校验
@Before(BlogValidator.class)
public void save() {
Blog me=getModel(Blog.class);
me.set("id", 2);
me.save();
redirect("/blog");
}
校验使用AOP拦截器实现。
页面数据处理
数据获取调用框架的getModel,将resquest中的数据自动映射到Blog类中;也可以在Controller中直接获取数据,getPara(“id”);
持久层配置
单数据源配置
持久层使用ActiveRecord,以下是 Plugin 配置示例代码
C3p0Plugin cp = new C3p0Plugin("jdbc:mysql://localhost/db_name",
"userName", "password");
me.add(cp);
ActiveRecordPlugin arp = new ActiveRecordPlugin(cp);
me.add(arp);
arp.addMapping("user", User.class);
arp.addMapping("article", "article_id", Article.class);
以上代码配置了两个插件:C3p0Plugin 与 ActiveRecordPlugin,前者是 c3p0 数据源插件,ActiveReceord 中定义了 addMapping(String tableName, Class<? extends Model> modelClass>)方法,该方法建立了数据库表名到 Model 的映射关系。
User类定义如下:
public class User extends Model<User> {
public static final User dao = new User();
}
User类中无须定义属性,框架启动时会从数据库中把对应表“user”中的字段通过反射机制实例化到user中,通过user. getStr(String attr)获取从数据库中查询的数据,若数据库字段名有变动加别名解决应用需要同步修改的问题。
多数据源配置
// 配置Druid 数据库连接池插件
DruidPlugin dbPlugin = new DruidPlugin(getProperty("jdbcUrl"), getProperty("user"), getProperty("password") );
me.add(dbPlugin);
// 配置ActiveRecord插件
ActiveRecordPlugin arp = new ActiveRecordPlugin("mysql", dbPlugin);
me.add(arp);
// h2数据库
JdbcConnectionPool cpH2 = JdbcConnectionPool.create(MonitorConfig.dbUrl, MonitorConfig.dbUserName, MonitorConfig.dbPassword);
ActiveRecordPlugin arpH2 = new ActiveRecordPlugin("h2", cpH2);
me.add(arpH2);
arpH2.addMapping("blog", Blog.class); // 映射blog 表到 Blog模型
arp.addMapping("blog", Blog1.class); // 映射blog 表到 Blog模型
数据库操作
实体对应操作的数据库为ActiveRecordPlugin中配置的数据库,可以在初始化时指定不同的数据库,对应配置的代码为:arp.addMapping("user", User.class);操作的数据库对arp配置的数据库。
新增
@Before(BlogValidator.class)
public void save() {
Blog me=getModel(Blog.class);
me.set("id", 2);
me.save();
redirect("/blog");
}
另一种方式
Record user = new Record().set("name", "James").set("age", 25);
Db.save("user", user);
修改
@Before(BlogValidator.class)
public void update() {
getModel(Blog.class).update();
redirect("/blog");
}
删除
public void delete() {
Blog.me.deleteById(getParaToInt());
redirect("/blog");
}
另一种方式
// 删除id值为25的user表中的记录
Db.deleteById("user", 25);
单表查询
public void query() {
setAttr("blog", Blog.me.findById(getParaToInt()));
}
另一种方式
// 查询id值为25的user, 且仅仅取name与age两个字段的
user = Db.findById("user", 25, "name, age");
复杂sql查询
public void relation() {
String sql = "select b.*, u.user_name from blog b inner
join user u on b.user_id=u.id where b.id=?";
Blog blog = Blog.dao.findFirst(sql, 123);
String name = blog.getStr("user_name");
}
说明:返回的blog属性多了name,只要不重复就不会报错,相当于blog对象是的属性是不固定的,根据查询的结果动态增加。
另一种方式查询
// 查询 dsMysql数据源中的 user
List<Record> users = Db.use("mysql").find("select * from user");
// 查询 dsOracle数据源中的 blog
List<Record> blogs = Db.use("oracle").find("select * from blog");
数据库事物
boolean succeed = Db.tx(new IAtom(){
public boolean run() throws SQLException {
int count = Db.update("update account set cash = cash - ? where
id = ?", 100, 123);
int count2 = Db.update("update account set cash = cash + ? where
id = ?", 100, 456);
return count == 1 && count2 == 1;
}});
以上两次数据库更新操作在一个事务中执行,如果执行过程中发生异常或者 invoke()方法
返回 false,则自动回滚事务。
方法2
声名式事务处理
@Before(Tx.class)
public void trans_demo() {
…
}
返回页面数据处理
render 系列方法将渲染不同类型的视图并返回给客户端。JFinal 目前支持的视图类型有:
FreeMarker、JSP、Velocity、JSON、File、Text、Html 等等。除了 JFinal 支持的视图型以外,
还可以通过继承 Render 抽象类来无限扩展视图类型。
render(String view)使用例子:
方法调用 描述
render(”test.html”) 渲染名为 test.html 的视图,该视图的 全路径为”/path/test.html”
render(”/other_path/test.html”) 渲染名为 test.html 的视图,该视图的全路径为”/other_path/test.html”,即当参数以”/”开头时将采用绝对路径
其它 render 方法使用例子:
方法调用 描述
renderFreeMarker(”test.html”) 渲染 名为 test.html 的视图 , 且 视图类 型为FreeMarker。
renderJsp(”test.html”) 渲染名为 test.html 的视图,且视图类型为 Jsp。
renderVelocity(“test.html”) 渲染名为 test.html 的视图,且视图类型为 Velocity。
renderJson()将所有通过 Controller.setAttr(String, Object)设置的变量转换成 json 数据并渲染。
renderJson(“users”, userList) 以”users”为根,仅将 userList 中的数据转换成 json数据并渲染。
renderJson(user) 将 user 对象转换成 json 数据并渲染。
http://www.jfinal.com
renderJson(“{\”age\”:18}” ) 直接渲染 json 字符串。
renderJson(new String[]{“user”, “blog”})仅将 setAttr(“user”, user)与 setAttr(“blog”, blog)设置的属性转换成 json 并渲染。使用 setAttr 设置的其它属性并不转换为 json。
renderFile(“test.zip”); 渲染名为 test.zip 的文件,一般用于文件下载
renderText(“Hello JFinal”) 渲染纯文本内容”Hello JFinal”。
renderHtml(“Hello Html”) 渲染 Html 内容”Hello Html”。
renderError (404 , “test.html”) 渲染名为 test.html 的文件,且状态为 404。
renderError (500 , “test.html”) 渲染名为 test.html 的文件,且状态为 500。
renderNull() 不渲染,即不向客户端返回数据。
render(new XmlRender())使用自定义的 XmlRender 来渲染。
结论
通过研究发现JFinal不但可以很好的代替SSH作为Java Web开发的首选框架,而且该框架的思想使java获得第二春,它改变了我们对传统java框架的认识,与Ruby、Python等动态语言的开发效率相媲美;该框架虽然为国人开发,但文档齐全,目前还有视频教学,极大降低了开发人员的学习成本,有利于新手快速入门,比起流行的SSH框架学习成本要低很高。Jfinal为开源框架,源代码非常小,可以快速地通读源码,对源码的充分理解解决了外部框架不可控的问题。
附录
官网
http://www.jfinal.com/
视频文档:
http://jfinalxm.sturgeon.mopaas.com/
jfinal-ext介绍
是对java极速web框架 jfinal 的一个扩充,主要利用jfinal微内核高扩展的特性扩展常用的实用功能和集成各种第三方框架,简化开发者的学习应用成本,引入了guava和joor包,代码更简洁。
常用的插件基本都有
其它插件介绍
cn.dreampie.jfinal-tablebind
https://github.com/Dreampie/jfinal-tablebind jfinal的table自动绑定插件,支持多数据源
cn.dreampie.jfinal-quartz
https://github.com/Dreampie/jfinal-quartz 基于jfinal 的quartz管理器
cn.dreampie.jfinal-sqlinxml
https://github.com/Dreampie/jfinal-sqlinxml 基于jfinal 的类似ibatis的sql语句管理方案
cn.dreampie.jfinal-akka
https://github.com/Dreampie/jfinal-akka java使用akka执行异步任务
cn.dreampie.jfinal-mailer
https://github.com/Dreampie/jfinal-mailer 使用akka发布邮件的jfinal插件
cn.dreampie.jfinal-slf4j
https://github.com/Dreampie/jfinal-slf4j 让jfinal使用slf4j的日志api
cn.dreampie.jfinal-lesscss
https://github.com/Dreampie/jfinal-lesscss java实现的lesscsss实时编译插件,可以由于jfinal
cn.dreampie.jfinal-shiro
https://github.com/Dreampie/jfinal-shiro 支持注解和数据库配置的shiro插件
cn.dreampie.jfinal-shiro-freemarker
https://github.com/Dreampie/jfinal-shiro-freemarker shiro插件实现的freemarker标签库
cn.dreampie.jfinal-web
https://github.com/Dreampie/jfinal-web 相关web插件,简洁model实现
cn.dreampie.jfinal-utils
https://github.com/Dreampie/jfinal-utils 部分jfinal工具
cn.dreampie.jfinal-flyway
https://github.com/Dreampie/jfinal-flyway 数据库脚本升级插件,开发中升级应用时,使用脚本同步升级数据库或者回滚
cn.dreampie.jfinal-captcha
基于jfinal render的超简单验证吗插件
cn.dreampie.jfinal-coffeescript
https://github.com/Dreampie/jfinal-coffeescript java实现的coffeescript实时编译插件
![](http://static.oschina.net/uploads/space/2015/0429/153109_is7j_1380141.jpg)
相关文章推荐
- 微软 Expression web3 抢先试用报告(附下载地址)
- 一个非Apple粉丝的ipad试用报告
- 稳安快ghost win7 x64 sp1 超级精简版v2.0试用报告
- Beta版本——用户试用与调研报告
- Nexus 7试用报告: 触摸彪悍外表下的软肋
- 活动助手Beta用户试用报告
- office 2013安装试用简单报告
- 金山手机安全卫士试用报告
- WEB打印新产品——Turbo ePrinting 试用报告(续4)
- 卡巴斯基试用报告
- 新鲜!Vista侧边栏在XP系统下的试用报告
- 微软 Expression web2 抢先试用报告(附下载地址和安装激活注册码)
- 【i.MX6UL试用体验】结项报告-天嵌科技医疗监护仪
- 圆刚高清电视棒各地区网友试用报告(3)
- Android 性能测试报告工具 battery-historian试用
- 酷派新智能手机N930试用报告
- OOJ网址大暴光及试用报告
- Windows 10 中文技术预览版个人试用报告详细介绍
- .NET混淆器试用报告