记录第一次使用JFinal,从简单的框架搭建到增删改查,从自带的方法到正常框架习惯的使用方式。
JFinal官网:http://www.jfinal.com/
JFinal 是基于 Java 语言的极速 WEB + ORM 框架,其核心设计目标是开发迅速、代码量少、学习简单、功能强大、轻量级、易扩展、Restful。在拥有Java语言所有优势的同时再拥有ruby、python、php等动态语言的开发效率。
JFinal有如下主要特点:
MVC架构,设计精巧,使用简单
遵循COC原则,零配置,无xml
独创Db + Record模式,灵活便利
ActiveRecord支持,使数据库开发极致快速
自动加载修改后的java文件,开发过程中无需重启web server
AOP支持,拦截器配置灵活,功能强大
Plugin体系结构,扩展性强
多视图支持,支持FreeMarker、JSP、Velocity
强大的Validator后端校验功能
功能齐全,拥有struts2的绝大部分功能
体积小仅632K,且无第三方依赖
例子:
本人用的maven,首先创建一个maven项目:
我的项目创建之后首先要设置:
然后点Apply
还有其他一些设置等等,我的问题,这里先跳过
然后在pom.xml中引入jar包:
maven搜索jar包:http://mvnrepository.com/
官方demo的pom.xml:
这里没有引入json,我的这个demo最后的方法需要json
4.0.0 com.demo jfinal_demo_for_maven war 3.2 jfinal_demo_for_maven Maven Webapp http://maven.apache.org UTF-8 UTF-8 ali-maven http://maven.aliyun.com/nexus/content/groups/public true true always fail junit junit 3.8.1 test com.jfinal jetty-server 8.1.8 compile com.jfinal jfinal 3.3 log4j log4j 1.2.16 mysql mysql-connector-java 5.1.44 com.alibaba druid 1.0.29 com.jfinal cos 2017.5 jfinal_demo_for_maven org.mortbay.jetty jetty-maven-plugin 8.1.8.v20121106 stop 5599 / 5 80 60000
然后是web.xml的配置:
注意:
DemoConfig.java 文件所在的包以及自身文件名必须与 web.xml 中的 param-value 标签内的配置相一致(在本例中该配置为 demo.DemoConfig)。
jfinal com.jfinal.core.JFinalFilter configClass demo.DemoConfig jfinal /*
接下来创建java文件:
创建DemoConfig并继承JFinalConfig,DemoConfig是主文件,运行这个文件启动项目,就像运行普通java文件main一样,同时运行之后如果修改其他代码,并不需要重启,框架会自动修改,直接刷新就可以看到修改后的内容。
这是初始的简单的demo:
package demo; import com.jfinal.config.*; public class DemoConfig extends JFinalConfig { public void configConstant(Constants me) { me.setDevMode(true); } public void configRoute(Routes me) { me.add("/hello", HelloController.class); } public void configEngine(Engine me) {} public void configPlugin(Plugins me) {} public void configInterceptor(Interceptors me) {} public void configHandler(Handlers me) {} }
然后配置controller:
package demo; import com.jfinal.core.Controller; public class HelloController extends Controller { public void index() { renderText("Hello JFinal World."); } }
然后直接打开浏览器输入http://localhost/hello 就可以看到页面输出了 Hello JFinal World 。
这是最基本的使用的例子,下面是我的程序:
package demo; import com.jfinal.config.*; import com.jfinal.core.JFinal; import com.jfinal.kit.PropKit; import com.jfinal.plugin.activerecord.ActiveRecordPlugin; import com.jfinal.plugin.c3p0.C3p0Plugin; import com.jfinal.plugin.druid.DruidPlugin; import com.jfinal.template.Engine; import controller.StudentController; import demo.model.Classes; import demo.model.Student; public class DemoConfig extends JFinalConfig { public static void main(String[] args) { JFinal.start("src/main/webapp", 80, "/", 5); } public void configConstant(Constants me) { me.setDevMode(true); //此方法用来配置 JFinal 常量值,如开发模式常量 devMode 的配置,如下代码配置了 JFinal //运行在开发模式:在开发模式下,JFinal 会对每次请求输出报告,如输出本次请求的 URL、Controller、Method //以及请求所携带的参数。 } public void configRoute(Routes me) { me.add("/", HelloController.class); me.add("/test/mytest", HelloController.class,"test"); me.add("/student", StudentController.class); //me.add("/classes", ClassesController.class); } public void configEngine(Engine me) { } public void configPlugin(Plugins me) { // C3p0Plugin cp = new C3p0Plugin("jdbc:mysql://localhost/db_name", // "userName", "password"); // me.add(cp); loadPropertyFile("a_little_config.txt"); DruidPlugin dp = new DruidPlugin(getProperty("jdbcUrl"), getProperty("user"), getProperty("password")); me.add(dp); ActiveRecordPlugin arp = new ActiveRecordPlugin(dp); me.add(arp); arp.addMapping("student", "studentid", Student.class); arp.addMapping("classes", "classesid", Classes.class); // 此方法用来配置JFinal的Plugin,如下代码配置了Druid数据库连接池插件与ActiveRecord // 数据库访问插件。通过以下的配置,可以在应用中使用 ActiveRecord 非常方便地操作数据库。 } public void configInterceptor(Interceptors me) { //me.add(new AuthInterceptor()); // 此方法用来配置 JFinal 的全局拦截器,全局拦截器将拦截所有 action 请求,除非使用 // @Clear 在 Controller 中清除,如下代码配置了名为 AuthInterceptor 的拦截器。 } public void configHandler(Handlers me) { } }
这里面各个方法的简单说明都写在注释里了。
然后是controller:
这里虽然声明了service,但是并没有使用的,都是直接在controller方法里使用dao
package controller; import java.util.List; import java.util.Map; import com.alibaba.fastjson.JSONObject; import com.jfinal.aop.Before; import com.jfinal.core.Controller; import StudentInterceptor.StudentInterceptor; import StudentValidator.StudentValidator; import StudentValidator.StudentValidator2; import demo.model.Student; import service.StudentService; public class StudentController extends Controller { /** * 获取studentid那里有多种方法,这个要和前台传参写法一致,Controller 提供了 getPara 系列方法,官网api里很详细 jfinal用的是原生态sql语句,简单,方便,setAttr("studentList", list);把结果集放到request范围里, jfinal也有直接获取表单里分装成对象的方法 getModel(Student.class);就是,和struts2一样,表单name对应上就可以了,非常方便 添加那里对于oracle用序列维护studentid student.set("studentid", "mysequence.nextval").save(); jfinal有多种返回方式,也可以返回json数据,render 系列方法,官网api里很详细 */ static StudentService service = new StudentService(); @Before(StudentInterceptor.class) public void index() { Listlist = Student.dao.find("select * from student"); setAttr("studentList", list); //注意下面路径的的前面如果带/则从根目录下开始找,也就是说 下代码 = render("/student/index.html"); render("index.html"); } public void add() { render("add.html"); } public void test() { List list = Student.dao.find("select * from student"); setAttr("studentList", list); setAttr("student", list.get(0)); render("test.jsp"); } public void getlist() { List list = Student.dao.find("select * from student"); JSONObject jo = new JSONObject(); jo.put("code", 0); jo.put("msg", true); jo.put("count",list.size()); jo.put("data", list); renderJson(jo); } public void layui() { List list = Student.dao.find("select * from student"); setAttr("studentList", list); render("index3.html"); } public void delete() { // 获取表单域名为studentid的值 Student.dao.deleteById(getPara("studentid")); forwardAction("/student"); } public void delete1() { // 获取url请求中第一个值 Student.dao.deleteById(getParaToInt()); forwardAction("/student"); } public void update() { Student student = getModel(Student.class); student.update(); forwardAction("/student"); } public void get() { Student student = Student.dao.findById(getPara("studentid")); setAttr("student", student); render("index2.html"); } public void get1() { Student student = Student.dao.findById(getParaToInt()); setAttr("student", student); render("index2.html"); } @Before(StudentValidator.class) public void save() { /** * getModel用来接收页面表单域传递过来的model对象,表单域名称以”modelName.attrName” http://www.jfinal.com 方式命名,getModel 使用的 attrName 必须与数据表字段名完全一样。 getBean 方法用于支持传统 Java Bean,包括支持使用 jfnal 生成器生成了 getter、setter 方法 的 Model,页面表单传参时使用与 setter 方法相一致的 attrName,而非数据表字段名。 getModel与getBean区别在于前者使用数表字段名而后者使用与setter方法一致的属性名进 行数据注入。建议优先使用 getBean 方法。 */ //getBean(Student.class).save(); getModel(Student.class).save(); redirect("/student"); } @Before(StudentValidator2.class) public void savebean() { getBean(Student.class).save(); redirect("/student"); } }
同样的简单的说明也写在注释里了。
方法基本上都在这里了,下面是其他的一些配置:
这是实体类:
package demo.model; import com.jfinal.plugin.activerecord.Model; public class Student extends Model{ public static final Student dao = new Student(); /** * ActiveRecord 是 jfinal 最核心的组成部分之一,通过 ActiveRecord 来操作数据库,将极大地减少代码量,极大地提升开发效率,配置在后面,我这里用的是Model,Model 是 ActiveRecord 中最重要的组件之一,它充当 MVC 模式中的 Model部分。 以上代码中的 User 通过继承 Model,便立即拥有的众多方便的操作数据库的方法。在 User 中声明的 dao 静态对象是为了方便查询操作而定义的,该对象并不是必须的。 基于ActiveRecord 的 Model 无需定义属性, 无需定义 getter、 setter方法,无需 XML 配置,无需 Annotation 配置,极大降低了代码量。Model常见方法见官方API。 JFinal还有 独创 Db + Record 模式,Db 类及其配套的 Record 类, 提供了在 Model 类之外更为丰富的数据库操作功能。使用 Db 与 Record 类时,无需对数据库表进行映射,Record 相当于一个通用的 Model。Db常见方法见官方API。 */ }
StudentValidator:
package StudentValidator; import com.jfinal.core.Controller; import com.jfinal.validate.Validator; public class StudentValidator extends Validator { //在校验失败时才会调用 @Override protected void handleError(Controller controller) { controller.keepPara("student.studentname");//将提交的值再传回页面以便保持原先输入的值 controller.render("/add.html"); } @Override protected void validate(Controller controller) { //验证表单域name,返回信息key,返回信息value validateRequiredString("student.studentname", "studentnameMsg", "请输入学生名称!"); } }
package StudentValidator; import com.jfinal.core.Controller; import com.jfinal.validate.Validator; public class StudentValidator2 extends Validator { //在校验失败时才会调用 @Override protected void handleError(Controller controller) { controller.keepPara("studentname");//将提交的值再传回页面以便保持原先输入的值 controller.render("/add.html"); } @Override protected void validate(Controller controller) { //验证表单域name,返回信息key,返回信息value validateRequiredString("studentname", "studentnameMsg", "请输入学生名称!"); } }
StudentInterceptor:
package StudentInterceptor; import com.jfinal.aop.Interceptor; import com.jfinal.aop.Invocation; public class StudentInterceptor implements Interceptor { public void intercept(Invocation ai) { System.out.println("Before action invoking"); ai.invoke(); System.out.println("After action invoking"); } }
然后是前台的显示页面:
关于前台页面,需要看一下文档第六章,JFinal模板引擎的内容,了解JFinal如何在前台显示,这是很重要的
删除 #for(x : [1..10]) #(x) #end学生管理 学生管理
测试layui 编辑索引0
添加
id | 姓名 | 性别 | 年龄 | 地址 | 邮箱 | 操作 |
---|---|---|---|---|---|---|
#(x.studentid) | #(x.studentname) | #(x.sex) | #(x.age) | #(x.address) | #(x.email) | 删除 删除 修改 修改1 |
这就是页面效果,因为没有样式所以看起来比较粗狂,然后下面是用正常使用的layui,加上正常习惯的方法返回数据组成的:
这样感觉稍微好了一点,因为只是第一次使用,做一个测试,所以还是比较粗犷的。
然后需要注意的是这种方式的数据返回的问题:
public void getlist() { Listlist = Student.dao.find("select * from student"); JSONObject jo = new JSONObject(); jo.put("code", 0); jo.put("msg", true); jo.put("count",list.size()); jo.put("data", list); renderJson(jo); }
这是layui表格url指向的方法,在这里,需要将json数据用renderJson的方式返回。
然后需要 注意的是,我尝试过直接返回list集合,貌似方法是可行的,只是因为layui表格必须是以上格式才能接收数据所以没有显示到页面上,但是当我直接return jo的时候后台报错,这个问题只能等明天在学习并解决了。
以下是返回的render方法的几种使用方式:
然后需要注意的是方法的调用和传参:
如下两种方法和传参的方式:
下面是controller方法:
public void delete() { // 获取表单域名为studentid的值 Student.dao.deleteById(getPara("studentid")); forwardAction("/student"); } public void delete1() { // 获取url请求中第一个值 Student.dao.deleteById(getParaToInt()); forwardAction("/student"); } public void update() { Student student = getModel(Student.class); student.update(); forwardAction("/student"); } public void get() { Student student = Student.dao.findById(getPara("studentid")); setAttr("student", student); render("index2.html"); } public void get1() { Student student = Student.dao.findById(getParaToInt()); setAttr("student", student); render("index2.html"); }
最后就是添加接受实体类的两种方式:
@Before(StudentValidator.class) public void save() { /** * getModel用来接收页面表单域传递过来的model对象,表单域名称以”modelName.attrName” http://www.jfinal.com 方式命名,getModel 使用的 attrName 必须与数据表字段名完全一样。 getBean 方法用于支持传统 Java Bean,包括支持使用 jfnal 生成器生成了 getter、setter 方法 的 Model,页面表单传参时使用与 setter 方法相一致的 attrName,而非数据表字段名。 getModel与getBean区别在于前者使用数表字段名而后者使用与setter方法一致的属性名进 行数据注入。建议优先使用 getBean 方法。 */ //getBean(Student.class).save(); getModel(Student.class).save(); redirect("/student"); } @Before(StudentValidator2.class) public void savebean() { getBean(Student.class).save(); redirect("/student"); }
其中第二中的getBean方式在我这个demo中,可能由于没有设置getset的原因,添加之后是只有生成了ID,没有其他数据的。
如果需要使用。下面是官方demo的写法:
package com.demo.common.model; import com.demo.common.model.base.BaseBlog; /** * 本 demo 仅表达最为粗浅的 jfinal 用法,更为有价值的实用的企业级用法 * 详见 JFinal 俱乐部: http://jfinal.com/club * * Blog model. * 数据库字段名建议使用驼峰命名规则,便于与 java 代码保持一致,如字段名: userId */ @SuppressWarnings("serial") public class Blog extends BaseBlog{ }
package com.demo.common.model.base; import com.jfinal.plugin.activerecord.Model; import com.jfinal.plugin.activerecord.IBean; /** * Generated by JFinal, do not modify this file. */ @SuppressWarnings({"serial", "unchecked"}) public abstract class BaseBlog> extends Model implements IBean { public M setId(java.lang.Integer id) { set("id", id); return (M)this; } public java.lang.Integer getId() { return getInt("id"); } public M setTitle(java.lang.String title) { set("title", title); return (M)this; } public java.lang.String getTitle() { return getStr("title"); } public M setContent(java.lang.String content) { set("content", content); return (M)this; } public java.lang.String getContent() { return getStr("content"); } }
以上这篇JFinal极速开发框架使用笔记分享就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持脚本之家。