JFinal极速开发框架使用笔记分享

网友投稿 617 2023-03-01


JFinal极速开发框架使用笔记分享

记录第一次使用JFinal,从简单的框架搭建到增删改查,从自带的方法到正常框架习惯的使用方式。

JFinal官网:http://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

xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

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

xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

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

/*

aWVhqik

接下来创建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() {

List list = 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://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如何在前台显示,这是很重要的

测试layui

编辑索引0

添加

id:

删除

id:

#for(x : [1..10])

#(x)

#end

#for(x : studentList)

  删除

  删除

  修改

  修改1

#end

这就是页面效果,因为没有样式所以看起来比较粗狂,然后下面是用正常使用的layui,加上正常习惯的方法返回数据组成的:

class="layui-btn layui-btn-small">

添加

onsubmit="return false">

搜索用户:

autocomplete="off">

data-type="reload">搜索

lay-data="{url:'/student/getlist',id:'idTest',height: 'full-60' ,}"

lay-filter="demo">

id

姓名

性别

年龄

地址

这样感觉稍微好了一点,因为只是第一次使用,做一个测试,所以还是比较粗犷的。

然后需要注意的是这种方式的数据返回的问题:

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);

}

这是layui表格url指向的方法,在这里,需要将json数据用renderJson的方式返回。

然后需要 注意的是,我尝试过直接返回list集合,貌似方法是可行的,只是因为layui表格必须是以上格式才能接收数据所以没有显示到页面上,但是当我直接return jo的时候后台报错,这个问题只能等明天在学习并解决了。

以下是返回的render方法的几种使用方式:

然后需要注意的是方法的调用和传参:

如下两种方法和传参的方式:

删除

  删除

  修改

  修改1

下面是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://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");

}

}


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Windows下安装ElasticSearch的方法(图文)
下一篇:Node使用Sequlize连接Mysql报错:Access denied for user ‘xxx’@‘localhost’
相关文章

 发表评论

暂时没有评论,来抢沙发吧~