初学Jfinal

刚接触JFianl觉得开发很方便,JFinal的主要特点及优势如下: 

    1、MVC架构,设计精巧,使用简单;

    2、遵循COC原则,零配置,无xml;

    3、ActiveRecord支持,使数据库开发极致快速;

    4、自动加载修改后的java文件,开发过程中无需重启Web server;

    5、AOP支持,拦截器配置灵活,功能强大;

    6、Plugin体系结构,扩展性强;

    7、多视图支持,支持FreeMarker、JSP、Velocity;

    8、强大的Validator后端校验功能;

    9、功能齐全,拥有Struts2的绝大部分功能;

    10、体积小仅180K,且无第三方依赖;

一、基于JFinal的web项目都需要创建一个继承自JFinalConfig类的子类,该类用于对整个web项目进行配置。并重写6个方法

public class BaseConfig extends JFinalConfig {
  
    public void configConstant(Constants me) {}

    public void configRoute(Routes me) {}

    public void configEngine(Engine me) {}

    public void configPlugin(Plugins me) {}

    public void configInterceptor(Interceptors me) {}

    public void configHandler(Handlers handlers) {}
}

 1.配置常量

/**
 * 配置JFinal常量值
 * @param me
 */
public void configConstant(Constants me) {
    me.setReportAfterInvocation(false);//设置 devMode 之下的 action report 是否在 invocation 之后,默认值为 true
    PropKit.use("jdbc.properties");//读取配置文件
    me.setDevMode(true);//设置开发模式
}

2.配置路由

/**
 * 配置访问路由
 * @param me
 */
public void configRoute(Routes me) {
    me.setBaseViewPath("/view") //设置基础路径,渲染的页面都在/view目录下
    me.add("/hello", HelloController.class);    // "/hello"表示通过这个路径映射到HelloController上
    me.add("/", BlogController.class, "/blog");// "/"表示通过这个路径映射到BlogController上,之后返回blog目录所在的渲染页面html、jsp上
}

3.配置Template Engine

/**
 * 配置引擎
 * @param me
 */
public void configEngine(Engine me) {
    me.addSharedFunction("/view/common/_layout.html");//设置共享页面,在页面上通过#define layout()定义模板,#@layout()引用
    me.addSharedFunction("/view/common/_layopen.html");
}

4.配置访问插件

public void configPlugin(Plugins me) {
    DruidPlugin dp = new DruidPlugin(PropKit.get("jdbcUrl"), PropKit.get("user"), PropKit.get("password"));
    me.add(dp); //配置数据库连接池

    ActiveRecordPlugin arp = new ActiveRecordPlugin(dp);//建立数据库表名到Model的映射关系
    /*arp.addMapping("blog", "id", Blog.class);*/
    _MappingKit.mapping(arp); //自动生成_MappingKit,相当于注释的arp.addMapping("blog", "id", Blog.class);
    me.add(arp);
}

5.拦截器配置

public void configInterceptor(Interceptors me) {}

6.配置处理器

public void configHandler(Handlers me) {}

二、Controller

1.Action

     在 Controller 之中定义的 public 方法称为Action。Action 是请求的最小单位。Action 方法必须在 Controller 中定义,且必须是 public 可见性。

    下例通过访问路径:localhost/index就可以访问到

 public void index(){
    render("list.html");
 }

2 参数获取

    2.1  getPara系列方法分为两种类型。

        第一种类型为第一个形参为String的getPara系列方法

        第二种类型为第一个形参为int或无形参的getPara系列方法

        如果请求访问方式为问号传参:localhost/list?page=1,getPara接收方式为String page = getParaToInt("page");

        如果请求访问方式为Restful传参:localhost/list/1,getPara接收方式为String page = getParaToInt(0);

    2.2 getModel / getBean 

        getModel 用来接收页面表单域传递过来的model对象,表单域名称以”modelName.attrName”方式命名,getModel使用的attrName必须与数据表字段名完全一样。

         getBean 方法用于支持传统Java Bean,包括支持使用jfinal生成器生成了getter、setter方法的Model,页面表单传参时使用与setter方法相一致的attrName,而非数据表字段名。

public  void submit(){
    Blog blog = getModel(Blog.class,"blog");
    blog.save();
    redirect("/");
}

    2.3 set / setAttr 方法  :  该方法可以将各种数据传递给View并在View中显示出来。

public void index(){

    List<Blog> blogs = Blog.blogDao.find("select * from blog");
    setAttr("blogs",blogs);
    render("list.html");
}

三、Aop

  1. Intercepter  自定义Intercepter类实现Interceptor类,编写intercept方法,必须调用 inv.invoke() 方法,才能将当前调用传递到后续的 Interceptor 与 Action

public class BlogIntercepter implements Interceptor {
    public void intercept(Invocation invocation) {
        System.out.println("before");
        invocation.invoke();
        System.out.println("after");
    }
}

    2.@Before  对拦截器进行配置

@Before(BlogIntercepter.class)
public void index(){
    List<Blog> blogs = Blog.blogDao.find("select * from blog");
    setAttr("blogs",blogs);
    render("list.html");
}

    3.@Clear  携带参数时清除目标层中指定的拦截器。Clear注解带有参数时,能清除指定的拦截器

@Clear(BlogIntercepter.class)
public  void submit(){
    Blog blog = getModel(Blog.class,"blog");
    blog.save();
    redirect("/");
}

四、ActiveRecord

  1. Model   Blog通过继承Model,便立即拥有的众多方便的操作数据库的方法

public class Blog extends Model<Blog> {

    public static final Blog blogDao = new Blog();
}

image.png

2.Db+Record  使用Db与Record类时,无需对数据库表进行映射,Record相当于一个通用的Model

image.png

Db+RecordModel功能相似

相同点:
1、两者都提供了增删改查的数据库操作功能,两者查询相关功能最终都是通过 sql 查询操作。
2、两者都具有查询映射对象、查询属性、分页查询、缓存查询功能。
3、在 findXXX系列的方法中通过 ModelBuilder类和 RecordBuilder类 中的 build方法将查询结构构建成映射对象,DB构建成 Record通用的映射对象,Model构建成了具体集成此类的映射对象。在查询中最终基本是构建查询sql、执行sql获取结果集、构建映射对象结果集同一套流程。

不同点:
1DB 在使用中面向数据库,通过 sql 进行简单灵活的数据操作。Model 在使用中面向映射对象,直接操作对象进行更丰富和复杂的操作。
2DB 中查询方法返回单个类型值或者 Record 类型,Model 中查询方法返回单个类型值或者继承此类的对象类型。
3DB Model 中多了批量处理的一系列方法。

五、Validator

Validator自身实现了Interceptor接口,所以它也是一个拦截器,配置方式与拦截器完全一样

public class BlogValidator extends Validator {
    protected void validate(Controller controller) {
        validateRequiredString("blog.title","msg","请输入标题");   //前台页面通过msg弹出错误信息
    }
}
/**
 * 提交方法
 */
@Before(BlogValidator.class) //验证信息拦截
public  void submit(){
    Blog blog = getModel(Blog.class,"blog");
    blog.save();
   renderJson(Ret.ok());
}

六、模板引擎

#if(c1)..#else if(c2)..#else..#end   if判断用法

for基本用法

// 对 List、数组、Set 这类结构进行迭代
#for(x : list)
  #(x.field)
#end
 
// 对 Map 进行迭代
#for(x : map)
  #(x.key)
  #(x.value)
#end

switch用法

#switch (month)
  #case (1, 3, 5, 7, 8, 10, 12)
    #(month) 月有 31 天
  #case (2)
    #(month) 月平年有28天,闰年有29天
  #default
    月份错误: #(month ?? "null")
#end

#include用于将外部模板内容包含进来

#define xx() ...#end可以定义模板函数

#define content()
<div>
   这里是模板内容部分,相当于传统模板引擎的 nested 的部分
</div>
#end

#@xx() 引用某个名为xx()的模板

#@content()//引用


评论区

david wang

2019-07-11 17:22

666,加油

JFinal

2019-07-12 10:05

谢谢分享