文档章节

Jfinal试用报告

清风郎月
 清风郎月
发布于 2015/04/29 13:53
字数 2662
阅读 285
收藏 4
点赞 0
评论 2

前言

    为了解决现有的开发框架配置繁琐,开发效率不高的问题。同时能适应简单业务快速开发的功能,适应多样化需求的变动减少开发人员繁琐、重复的劳动,专注于业务实现。通过讨论认为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。


 

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实时编译插件

© 著作权归作者所有

共有 人打赏支持
清风郎月

清风郎月

粉丝 6
博文 2
码字总数 2662
作品 1
杭州
后端工程师
加载中

评论(2)

清风郎月
清风郎月
JFinal Extensions 2.0 发布
JFinal Extensions 的详细介绍:请点这里
JFinal Extensions 的下载地址:请点这里
JFinal Extensions 的源码地址:http://git.oschina.net/zhouleib1412/jfinal-ext
Jfinal-ext2.1 AutoBindRoutes功能
清风郎月
清风郎月
专业收藏各类 jfinal插件,今天又收了一个
jfinalGrid
表格哪东西
JfinalUIB 是 Jfinal + beetl + postgresql + ehcache + charisma实现的用户权限管理系统

详细介绍:http://my.oschina.net/dongcb678/blog/272036

代码地址:

https://code.jd.com/dongcb678/JfinalUIB.git

http://git.oschina.net/dongcb678/JfinalUIB.git
JFinal 3.4 发布,将极速贯彻到 UI 层

jfinal 的终极目标是全面实现软件开发整个过程的极速开发,极大提升开发效率,极大降低学习成本,极大提升开发体验 jfinal 诞生头五年,已实现 WEB + ORM + AOP 层面的极速开发,赢得了大量开...

JFinal ⋅ 04/28 ⋅ 129

JAVA 极速WEB+ORM框架 - JFinal

JFinal 是基于 Java 语言的极速 WEB + ORM 框架,其核心设计目标是开发迅速、代码量少、学习简单、功能强大、轻量级、易扩展、Restful。在拥有Java语言所有优势的同时再拥有ruby、python、p...

JFinal ⋅ 2012/03/18 ⋅ 496

JFinal 1.6可以无缝升级到最高哪个版本?

大约在JFinal 1.6的时候做了一个项目,一直运行至今。中途没升级也没做功能扩展,时至今日,需要做功能升级了,但是时隔太久远,基本不记得JFinal这个框架一路过来的升级过程了。所以想请求帮...

车开源 ⋅ 05/11 ⋅ 0

JFinal如何使用JNDI连接数据库

想用JNDI的方式连接数据库,但是JFinal中用的是DruidPlugin和ActiveRecordPlugin,没有看到用DataSource的地方?请问JFinal支持JNDI连接方式吗?怎么具体实现?...

zqq3436 ⋅ 06/11 ⋅ 0

Jboot v1.4.9 发布,核心 JFinal 升级到 3.4 最新版本

Jboot 是一个基于 JFinal 和 Undertow 开发的微服务框架。提供了 AOP、RPC、分布式缓存、限流、降级、熔断、统一配置中心、Opentracing 数据追踪、metrics 数据监控、分布式 session、代码生...

理工男海哥 ⋅ 05/03 ⋅ 0

jfinal兼容oracle integer字段

为什么oracle integer字段用了number(3,0),jfinal生成的字段还是BigDecimal @jfinal

tianxia007 ⋅ 05/02 ⋅ 0

基于注释自动生成 API 文档 - Regan API

Regan API 前言 Regan API 项目是基于注释自动生成api文档,很大缩短了开始与后期维护API接口文档的时间。 Regan API 利用jdk提供的Doclet 类读取文档注释,可手动配置需要读取的文件,同时增...

Jeff_Regan ⋅ 06/15 ⋅ 0

kiplinglee/jfinal-ioc-plugin

jfinal-ioc-plugin JFinal 依赖注入插件 1.在JFinalConfig文件中配置IOC插件 @Overridepublic void configConstant(Constants me) { // 创建controller实现依赖注入me.setControllerFactory......

kiplinglee ⋅ 04/13 ⋅ 0

JFinal(1.6)在Validator里执行过getFile,在Controller里取不到文件

JFinal在Validator里执行过getFile之后Validator中是可以取到文件及有关信息,但是在Controller里取不到文件,是不是我的姿势不正确?@JFinal

车开源 ⋅ 05/15 ⋅ 0

jfinal-admin 3.2 发布,beetl 模板升级到 2.7.14

jfinal-admin 3.2 版本正式发布啦。 基于JFinal的后台管理系统,采用了简洁强大的JFinal作为web框架,模板引擎用的是beetl,数据库用mysql,前端bootstrap框架。 演示地址 http://jad.yxyun...

IT小香猪 ⋅ 04/19 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

RabbitMQ学习以及与Spring的集成(三)

本文介绍RabbitMQ与Spring的简单集成以及消息的发送和接收。 在RabbitMQ的Spring配置文件中,首先需要增加命名空间。 xmlns:rabbit="http://www.springframework.org/schema/rabbit" 其次是模...

onedotdot ⋅ 27分钟前 ⋅ 0

JAVA实现仿微信红包分配规则

最近过年发红包拜年成为一种新的潮流,作为程序猿对算法的好奇远远要大于对红包的好奇,这里介绍一种自己想到的一种随机红包分配策略,还请大家多多指教。 算法介绍 一、红包金额限制 对于微...

小致dad ⋅ 39分钟前 ⋅ 0

Python 数电表格格式化 xlutils xlwt xlrd的使用

需要安装 xlutils xlwt xlrd 格式化前 格式化后 代码 先copy读取的表格,然后按照一定的规则修改,将昵称中的学号提取出来替换昵称即可 from xlrd import open_workbookfrom xlutils.copy ...

阿豪boy ⋅ 今天 ⋅ 0

面试题:使用rand5()生成rand7()

前言 读研究生这3 年,思维与本科相比变化挺大的,这几年除了看论文、设计方案,更重要的是学会注重先思考、再实现,感觉更加成熟吧,不再像个小P孩,人年轻时总会心高气傲。有1 道面试题:给...

初雪之音 ⋅ 今天 ⋅ 0

Docker Toolbox Looks like something went wrong

Docker Toolbox 重新安装后提示错误:Looks like something went wrong in step ´Checking if machine default exists´ 控制面板-->程序与应用-->启用或关闭windows功能:找到Hyper-V,如果处......

随你疯 ⋅ 今天 ⋅ 0

Guacamole 远程桌面

本文将Apache的guacamole服务的部署和应用,http://guacamole.apache.org/doc/gug/ 该链接下有全部相关知识的英文文档,如果水平ok,可以去这里仔细查看。 一、简介 Apache Guacamole 是无客...

千里明月 ⋅ 今天 ⋅ 0

nagios 安装

Nagios简介:监控网络并排除网络故障的工具:nagios,Ntop,OpenVAS,OCS,OSSIM等开源监控工具。 可以实现对网络上的服务器进行全面的监控,包括服务(apache、mysql、ntp、ftp、disk、qmail和h...

寰宇01 ⋅ 今天 ⋅ 0

AngularDart注意事项

默认情况下创建Dart项目应出现以下列表: 有时会因为不知明的原因导致列表项缺失: 此时可以通过以下步骤解决: 1.创建项目涉及到的包:stagehand 2.执行pub global activate stagehand或pub...

scooplol ⋅ 今天 ⋅ 0

Java Web如何操作Cookie的添加修改和删除

创建Cookie对象 Cookie cookie = new Cookie("id", "1"); 修改Cookie值 cookie.setValue("2"); 设置Cookie有效期和删除Cookie cookie.setMaxAge(24*60*60); // Cookie有效时间 co......

二营长意大利炮 ⋅ 今天 ⋅ 0

【每天一个JQuery特效】淡入淡出显示或隐藏窗口

我是JQuery新手爱好者,有时间就练练代码,防止手生,争取每天一个JQuery练习,在这个博客记录下学习的笔记。 本特效主要采用fadeIn()和fadeOut()方法显示淡入淡出的显示效果显示或隐藏元...

Rhymo-Wu ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部