当前位置: 首页 > 工具软件 > JFinal_Blog > 使用案例 >

JFinal

杨安歌
2023-12-01

JFinal简介

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

  2. 使用JFinal提供的逆向工程可以直接生成实体类以及JFinal需要的依赖类文件(_JFinalDemoGenerator类)。

核心配置类

  1. JFinal提供了JfinalConfig类来管理项目的全局配置。自创一个类继承自JfinalConfig类并实现方法。

    例如:

    1. configConstant(ConsTants c)

      • 配置项目全局常量

    2. configRoute(Routes r)

      • 配置路由。可以配置指定包下,也可以手动添加路由,映射到对应的Controller控制层。

    3. configEngine(Engine e)

      • 配置模板引擎(不常用)

    4. configPlugin(Plugins p)

      • 配置插件依赖

        例如:

        1. 配置druid数据库连接池插件

          DruidPlugin druidPlugin = new DruidPlugin(URL,username,password);

          p.add(druidPlugin);

        2. 配置ActiveRecord操作数据库插件,需要依赖于JFinal逆向工程生成的类做表字段映射。

          ActiveRecordPlugin arp = new ActiveRecordPlugin(druidPlugin);

          //使用逆向工程类自动做映射关系

          _MappingKit.mapping(arp);

          p.add(arp);

    5. configHandler(Handlers h) handler需要考虑线程安全问题

      • 用来配置handler,handler接管所有的web请求,方便进一步做扩展。

    6. configInterceptor(Interceptors i)

      • 使用JFinal拦截器需要实现Interceptor接口去实现intercept方法。

        • 配置拦截器,可以分为三种:全局拦截器、控制层拦截器、业务层拦截器

          全局拦截器此方法和addGlobalActionInterceptor()是等价的,拦截所有controller中action的方法

          i.add(new Inter());

          控制层拦截器

          i.addGlobalActionInterceptor(new Inter());

          业务层拦截器

          i.addGlobalServiceInterceptor(new Inter());

    7. onStart()、onStop()

      • 项目启动后需要执行的业务代码使用onStart()实现。

      • 项目关闭前需要执行的业务代码使用onStop()实现。

JFinal 控制层

  1. 控制层通过实现JFinal提供的类(Controller)实现控制层,并且是线程安全的。

  2. 通过在Controller类上加JFinal提供的@path注解来实现路由的定位。

  3. 在Controller中定义的方法,被public修饰的方法就可以称为一个action,action是每一个请求的最小单位。

  4. 如果不希望controller中的方法被修饰成action,可以使用@NotAction注解。

  5. 获取前端参数

    • get / getPara方法

    • getModel()

      1. 采用数据库表字段名来进行数据注入(不推荐使用)

      2. getModel()一共有四个具体实现:

        • getModel(Class<T> modelClass)

        • getModel(Class<T> modelClass, boolean skipConvertError)

        • getModel(Class<T> modelClass, String modelName)

        • getModel(Class<T> modelClass, String modelName, boolean skipConvertError)

    • getBean()

      1. 采用实体类set()方法进行数据注入(推荐使用)

      2. getBean()有四个方法实现:

        • getBean(Class<T> beanClass)

        • getBean(Class<T> beanClass, boolean skipConvertError)

        • getBean(Class<T> beanClass, String beanName)

        • getBean(Class<T> beanClass, String beanName, boolean skipConvertError)

  6. 获取后端参数(render)

    // 渲染名为test.html的视图,且视图类型为 JFinal Template
    renderTemplate(”test.html”);
     
    // 生成二维码
    renderQrCode("content");
     
    // 渲染名为test.html的视图,且视图类型为FreeMarker
    renderFreeMarker(”test.html”);
     
    // 渲染名为test.html的视图,且视图类型为Velocity
    renderVelocity(“test.html”);
     
    // 将所有setAttr(..)设置的变量转换成 json 并渲染
    renderJson();
     
    // 以 "users" 为根,仅将 userList 中的数据转换成 json 并渲染
    renderJson(“users”, userList);
     
    // 将user对象转换成 json 并渲染
    renderJson(user);
     
    // 直接渲染 json 字符串
    renderJson("{\"age\":18}" );
     
    // 仅将setAttr(“user”, user)与setAttr(“blog”, blog)设置的属性转换成json并渲染
    renderJson(new  String[]{"user", "blog"});
     
    // 渲染名为test.zip的文件,一般用于文件下载
    renderFile("test.zip");
     
    // 渲染纯文本内容 "Hello JFinal"
    renderText("Hello JFinal");
     
    // 渲染 Html 内容 "Hello Html"
    renderHtml("Hello Html");
     
    // 渲染名为 test.html 的文件,且状态为 404
    renderError(404 , "test.html");
     
    // 渲染名为 test.html 的文件,且状态为 500
    renderError(500 , "test.html");
     
    // 不渲染,即不向客户端返回数据
    renderNull();
     
    // 使用自定义的MyRender来渲染
    render(new MyRender());

JFinal AOP

  1. 在JFinal中简化了传统AOP的复杂实现方式,使用拦截器对方法实现的操作。

  2. intercepter、Before、Clear

    • intercepter可以对方法进行拦截,并在方法执行前后,执行切面代码。使用拦截器需要在配置类中指定拦截器,并实现JFinal提供的拦截器接口(Intercepter)重写其中intercept(Invocation invocation)方法,在其中写入被切入Action前后需要执行的逻辑代码。

    • Before是一个注解,主要作用于控制层和Action上,该注解有一个value,可以选择配置使用哪一种拦截器。

      • 使用在类上,表示对该类所有方法进行拦截,并且执行切面操作

      • 使用在Action上,表示对该方法进行拦截,执行切面操作

    • Clear是一个注解:拦截器从上到下依次分为 Global、Inject、Class、Method 四个层次,Clear 用于清除自身 所处层次以上层的拦截器。Clear 声明在 Method 层时将针对 Global、Inject、Class 进行清除。Clear 声明在 Class 层时 将针对 Global、Inject 进行清除。Clear 注解携带参数时清除目标层中指定的拦截器。clear可以配置清除指定的拦截器。

  3. Inject注解依赖注入

    • 使用Inject注解可以在controller、Intercepter中注入依赖对象。

逆向工程(自动生成Model、BaseModel、MappingKit、DataDictionary)

  1. JFinal提供了逆向工程工具类(Generator)

  2. 生成后的Model直接与javaBean无缝衔接,无需重写setter、getter方法。

    具体使用:

    // model 所使用的包名 (MappingKit 默认使用的包名)
            String modelPackageName = "com.demo.common.model";
            
            // base model 所使用的包名
            String baseModelPackageName = modelPackageName + ".base";
            
            // base model 文件保存路径
            String baseModelOutputDir = System.getProperty("user.dir")
                    + "/src/main/java/" + baseModelPackageName.replace('.', '/');
            
            System.out.println("输出路径:"+ baseModelOutputDir);
            
            // model 文件保存路径 (MappingKit 与 DataDictionary 文件默认保存路径)
            String modelOutputDir = baseModelOutputDir + "/..";
            
            // 创建生成器
            Generator generator = new Generator(getDataSource(), baseModelPackageName, baseModelOutputDir,          modelPackageName, modelOutputDir);
            
            // 配置是否生成备注
            generator.setGenerateRemarks(true);
            
            // 设置数据库方言
            generator.setDialect(new MysqlDialect());
            
            // 设置是否生成链式 setter 方法,强烈建议配置成 false,否则 fastjson 反序列化会跳过有返回值的 setter 方法
            generator.setGenerateChainSetter(false);
            
            // 添加不需要生成的表名到黑名单
            generator.addBlacklist("adv");
            
            // 设置是否在 Model 中生成 dao 对象
            generator.setGenerateDaoInModel(false);
            
            // 设置是否生成字典文件
            generator.setGenerateDataDictionary(false);
            
            // 设置需要被移除的表名前缀用于生成modelName。例如表名 "osc_user",移除前缀 "osc_"后生成的model名为 "User"而        // 非 OscUser
            generator.setRemovedTableNamePrefixes("t_");
            
            // 将 mysql 8 以及其它原因之下生成 jdk 8 日期类型映射为 java.util.Date,便于兼容老项目,也便于习惯使用 java.util.Date 的同学
            TypeMapping tm = new TypeMapping();
            tm.addMapping(LocalDateTime.class, Date.class);
            tm.addMapping(LocalDate.class, Date.class);
            // tm.addMapping(LocalTime.class, LocalTime.class);     // LocalTime 暂时不变
            generator.setTypeMapping(tm);
            
            // 生成
            generator.generate();

ActiveRecord

  1. JFinal提供ActiveRecord来操作数据库。ActiveRecord在JFinal中做作为插件而存在。使用的话需要在JfinalConfig中进行配置。

    例如:

    public void configPlugin(Plugins me) {
        //数据库连接信息
        DruidPlugin dp = new DruidPlugin("jdbc:mysql://localhost/db_name", "userName", "password");
        me.add(dp);
        //数据库操作类,引入配置
        ActiveRecordPlugin arp = new ActiveRecordPlugin(dp);
        me.add(arp);
        //下列方法表明数据库表与实体类的映射关系
        arp.addMapping("user", User.class);
        //指定表article表的主键为article_id
        arp.addMapping("article", "article_id", Article.class);
    }

    表的主键默认是"id",如果是其他名称,则需指定主键列名称

  2. model

    • Model是ActiveRecord中最重要的组件之一,它充当MVC模式中的Model部分。

      案例:

      // 只需要继承Model类,来实现数据库增删改查的操作
      public class UserService extends Model<User> {
          public static final User dao = new User().dao();
      };
      ​
      // 一些常用的方法
      // 创建name属性为James,age属性为25的User对象并添加到数据库
      new User().set("name", "James").set("age", 25).save();
      ​
      // 删除id值为25的User
      User.dao.deleteById(25);
      ​
      // 查询id值为25的User将其name属性改为James并更新到数据库
      User.dao.findById(25).set("name", "James").update();
      ​
      // 查询id值为25的user, 且仅仅取name与age两个字段的值
      User user = User.dao.findByIdLoadColumns(25, "name, age");
      ​
      // 获取user的name属性
      String userName = user.getStr("name");
      ​
      // 获取user的age属性
      Integer userAge = user.getInt("age");
      ​
      // 查询所有年龄大于18岁的user
      List<User> users = User.dao.find("select * from user where age>18");
      ​
      // 分页查询年龄大于18的user,当前页号为1,每页10个user
      Page<User> userPage = User.dao.paginate(1, 10, "select *", "from user where age > ?", 18);

  3. Db + Record模式(数据库操作扩展,更为方便的书写复杂sql)

    • Db类加Record类在Model之上又提供了完整的数据库增删改查操作,更为方便的实现数据库复杂查询的操作。

      案例:

      // 创建name属性为James,age属性为25的record对象并添加到数据库
      Record user = new Record().set("name", "James").set("age", 25);
      Db.save("user", user);
      ​
      // 删除id值为25的user表中的记录
      Db.deleteById("user", 25);
      ​
      // 查询id值为25的Record将其name属性改为James并更新到数据库
      user = Db.findById("user", 25).set("name", "James");
      Db.update("user", user);
      ​
      // 获取user的name属性
      String userName = user.getStr("name");
      // 获取user的age属性
      Integer userAge = user.getInt("age");
      ​
      // 查询所有年龄大于18岁的user
      List<Record> users = Db.find("select * from user where age > 18");
      ​
      // 分页查询年龄大于18的user,当前页号为1,每页10个user
      Page<Record> userPage = Db.paginate(1, 10, "select *", "from user where age > ?", 18);

  4. paginate(分页)

    案例:

    // 普通分页
    dao.paginate(1, 10, "select *", "from girl where age > ? and weight < ?", 18, 50);
    ​
    // 支持分页排序 例如:
    dao.paginate(1, 10, true, "select *", "from girl where age > ? group by age", 18);

EhCachePlugin(缓存插件)

  1. EhCachePlugin是JFinal集成的缓存插件,通过使用EhCachePlugin可以提高系统的并发访问速度。

  2. EhCachePlugin在JFinal中是作为插件而存在的,想要使用需要在JFinalConfig中进行配置。

    案例:

    public class DemoConfig extends JFinalConfig {
        public void configPlugin(Plugins me) {
            me.add(new EhCachePlugin());
        }
    }
  1. 具体使用

    // 在配置类中配置之后,只需要在Action中加上注解以及拦截器。当请求时如果缓存中有责直接反悔return,不回去出发Action,用法简单。
    @Before(CacheInterceptor.class)
    public void list() {
        List<Blog> blogList = Blog.dao.find("select * from blog");
        User user = User.dao.findById(getParaToInt());
        setAttr("blogList", blogList);
        setAttr("user", user);
        render("blog.html");
    }
  1. EvictInterceptor 缓存清除

    • EvictInterceptor 根据CacheName注解来清除缓存中的数据

      案例:

    // EvictInterceptor拦截器根据CacheName来清除缓存中的数据。在JFinal 3.6版本之后CacheName可以定义多个来达到清除多个缓存的效果, 例如:
    @Before(EvictInterceptor.class)
    @CacheName("blogList")
    public void update() {
    getModel(Blog.class).update();
    redirect("blog.html");
    }
    ​
    @Before(EvictInterceptor.class)
    @CacheName("blogList, hotBlogList")   // 逗号分隔多个 cacheName
    public void update() {
    ...
    }
  1. CacheKit 缓存操作工具类

    • get(String cacheName, Object key) // 表示从缓存中拉取数据

    • put(String cacheName, Object key, Object value) // 表示将从缓存中拿取数据

RedisPlugin(Redis插件)

Redis的极速化插件。使用RedisPlugin可以极度方便的使用redis,当然,在JFinal中想使用插件都需要在JFinal配置类中进行配置。RedisPlugin不仅提供丰富的RedisAPI,同时还支持多redis服务端。

Redis配置:

public class DemoConfig extends JFinalConfig {
  public void configPlugin(Plugins me) {
    // 用于缓存bbs模块的redis服务
    RedisPlugin bbsRedis = new RedisPlugin("bbs", "localhost");
    me.add(bbsRedis);
 
    // 用于缓存news模块的redis服务
    RedisPlugin newsRedis = new RedisPlugin("news", "192.168.3.9");
    me.add(newsRedis);
  }
}
​
// 依赖
<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>3.6.3</version>
</dependency>
 
<dependency>
    <groupId>de.ruedigermoeller</groupId>
    <artifactId>fst</artifactId>
    <version>2.57</version><!-- 注意:更高版本不支持 jdk 8 -->
</dependency>

更多相关操作请访问

JFinal Redis

Cron4jPlugin(任务调度的插件)

简介:Cron4jPlugin是JFinal集成的任务调度插件,通过使用Cron4jPlugin可以使用通用的cron表达式极为便利的实现任务调度功能。
​
 官网: [JFinal 任务调度](https://jfinal.com/doc/9-2)

Validator是JFinal校验组件

简介:Validator是JFinal校验组件,在Validator类中提供了非常方便的校验方法,学习简单,使用方便。
​
 官网:[JFinal 校验组件](https://jfinal.com/doc/10-1)
 类似资料:

相关阅读

相关文章

相关问答