1、概览
2、部分相关代码
2.1 DemoConfig.java
DemoConfig.java:全局配置类 (6个方法)
void configConstant(Constants me){} |
此方法用来配置JFinal的一些常量值,例如开发模式常量 devMode 的配置,默认视图类型 ViewType的配置,默认编码格式为UTF-8等。
me.setDevMode(p.getBoolean("devMode", false)); |
这里将开发模式配置为 false , true值为开发模式
me.setInjectDependency(true); |
配置依赖注入
me.setInjectSuperClass(true); |
配置依赖注入时,是否对被注入类的超类进行注入
还有很多项目的通用配置信息
void configRoute(Routes me){} |
这个方法是用来配置路由信息的,每创建一个controller就在这里配置一遍路由信息
me.add("/", IndexController.class, "/index"); // 第三个参数为该Controller的视图存放路径 me.add("/student", StudentController.class); // 第三个参数省略时默认与第一个参数值相同,在此即为 "/student" |
对应项目中的两个Controller
void configEngine(Engine me){} |
这里用来配置页面模板
me.addSharedFunction("/common/_layout.html"); me.addSharedFunction("/common/_paginate.html"); |
上面的方法向模板引擎中添加了2个定义了共享函数的模板文件。
void configPlugin(Plugin me){} |
这里用来配置JFinal的一些插件信息
DruidPlugin druidPlugin = new DruidPlugin(p.get("jdbcUrl"), p.get("user"), p.get("password")); me.add(druidPlugin); |
配置Druid的数据库连接池插件
ActiveRecordPlugin arp = new ActiveRecordPlugin(druidPlugin); |
配置ActiverRecord数据库访问插件
正常来说应该增加数据库访问的映射关系,例如:
arp.addMapping("user", User.class); |
本demo中利用MappingKit自动化完成,即将代码写在_MappingKit中
_MappingKit.mapping(arp); public class _MappingKit { public static void mapping(ActiveRecordPlugin arp) { arp.addMapping("student", "id", Student.class); } } |
public static DruidPlugin createDruidPlugin() { loadConfig(); return new DruidPlugin(p.get("jdbcUrl"), p.get("user"), p.get("password")); } |
这部分代码是用于创建Druid插件
一般第一次调用的话,用该方法,然后再次调用的话,会调用configPlugin中的方法。
void configInterceptor(Interceptors interceptor) |
此方法来配置JFinal的全局拦截器,全局拦截器将拦截所有的action请求,除非使用@Clear注解在Controller中清除,如下代码配置了名为AuthInterceptor的拦截器。
public void configInterceptor(Interceptors interceptor) { interceptor.add(new AuthInterceptor()); } |
此demo中没有配置
void configHandler(Handlers handler) |
此方法用来配置JFinal的Handler。Handler可以接管所有的web请求,并对应用拥有完全的控制权,可以很方便地实现更高层的功能性扩展。此demo中没有配置
相关代码:
点击查看代码
package com.demo.common;
import com.demo.student.StudentController;
import com.demo.common.model._MappingKit;
import com.demo.index.IndexController;
import com.jfinal.config.Constants;
import com.jfinal.config.Handlers;
import com.jfinal.config.Interceptors;
import com.jfinal.config.JFinalConfig;
import com.jfinal.config.Plugins;
import com.jfinal.config.Routes;
import com.jfinal.kit.Prop;
import com.jfinal.kit.PropKit;
import com.jfinal.plugin.activerecord.ActiveRecordPlugin;
import com.jfinal.plugin.druid.DruidPlugin;
import com.jfinal.server.undertow.UndertowServer;
import com.jfinal.template.Engine;
/**
* 本 demo 仅表达最为粗浅的 jfinal 用法,更为有价值的实用的企业级用法
* 详见 JFinal 俱乐部: http://jfinal.com/club
*
* API 引导式配置
*/
public class DemoConfig extends JFinalConfig {
static Prop p;
/**
* 启动入口,运行此 main 方法可以启动项目,此 main 方法可以放置在任意的 Class 类定义中,不一定要放于此
*/
public static void main(String[] args) {
UndertowServer.start(DemoConfig.class);
}
/**
* PropKit.useFirstFound(...) 使用参数中从左到右最先被找到的配置文件
* 从左到右依次去找配置,找到则立即加载并立即返回,后续配置将被忽略
*/
static void loadConfig() {
if (p == null) {
p = PropKit.useFirstFound("demo-config-pro.txt", "demo-config-dev.txt");
}
}
/**
* 配置常量
*/
public void configConstant(Constants me) {
loadConfig();
me.setDevMode(p.getBoolean("devMode", false));
/**
* 支持 Controller、Interceptor、Validator 之中使用 @Inject 注入业务层,并且自动实现 AOP
* 注入动作支持任意深度并自动处理循环注入
*/
me.setInjectDependency(true);
// 配置对超类中的属性进行注入
me.setInjectSuperClass(true);
}
/**
* 配置路由
*/
public void configRoute(Routes me) {
me.add("/", IndexController.class, "/index"); // 第三个参数为该Controller的视图存放路径
me.add("/student", StudentController.class); // 第三个参数省略时默认与第一个参数值相同,在此即为 "/blog"
}
public void configEngine(Engine me) {
me.addSharedFunction("/common/_layout.html");
me.addSharedFunction("/common/_paginate.html");
}
/**
* 配置插件
*/
public void configPlugin(Plugins me) {
// 配置 druid 数据库连接池插件
DruidPlugin druidPlugin = new DruidPlugin(p.get("jdbcUrl"), p.get("user"), p.get("password"));
me.add(druidPlugin);
// 配置ActiveRecord插件
ActiveRecordPlugin arp = new ActiveRecordPlugin(druidPlugin);
// 所有映射在 MappingKit 中自动化搞定
_MappingKit.mapping(arp);
me.add(arp);
}
public static DruidPlugin createDruidPlugin() {
loadConfig();
return new DruidPlugin(p.get("jdbcUrl"), p.get("user"), p.get("password"));
}
/**
* 配置全局拦截器
*/
public void configInterceptor(Interceptors me) {
}
/**
* 配置处理器
*/
public void configHandler(Handlers me) {
}
}
2.2 StudentController.java
@Inject StudentService service; |
Service 使用 @Inject 进行注入
这个类里面所有的实际方法返回类型都是void空类型,返回的内容靠render()进行控制,可以返回json也可以返回页面视图。具体功能通过调用Service中的接口实现。
@Before(StudentInterceptor.class) |
这个语句是用来添加事务回滚
方法体不能扑捉异常,所有的异常都抛出,当出现异常时事物将回滚
相关代码:
点击查看代码
package com.demo.student;
import com.jfinal.aop.Before;
import com.jfinal.aop.Inject;
import com.jfinal.core.Controller;
import com.demo.common.model.Student;
/**
* 本 demo 仅表达最为粗浅的 jfinal 用法,更为有价值的实用的企业级用法
* 详见 JFinal 俱乐部: http://jfinal.com/club
*
* 所有 sql 与业务逻辑写在 Service 中,不要放在 Model 中,更不
* 要放在 Controller 中,养成好习惯,有利于大型项目的开发与维护
*/
@Before(StudentInterceptor.class)
public class StudentController extends Controller {
@Inject
StudentService service;
public void index() {
setAttr("studentPage", service.paginate(getParaToInt(0, 1), 10));
render("student.html");
}
public void add() {
}
/**
* save 与 update 的业务逻辑在实际应用中也应该放在 serivce 之中,
* 并要对数据进正确性进行验证,在此仅为了偷懒
*/
@Before(StudentValidator.class)
public void save() {
getBean(Student.class).save();
redirect("/student");
}
public void edit() {
setAttr("student", service.findById(getParaToInt()));
}
/**
* save 与 update 的业务逻辑在实际应用中也应该放在 serivce 之中,
* 并要对数据进正确性进行验证,在此仅为了偷懒
*/
@Before(StudentValidator.class)
public void findById() {
service.findById(getParaToInt());
redirect("/student");
}
public void update() {
getBean(Student.class).update();
redirect("/student");
}
public void delete() {
service.deleteById(getParaToInt());
redirect("/student");
}
}
2.3 StudentService.java
点击查看代码
package com.demo.student;
import com.demo.common.model.Student;
import com.jfinal.plugin.activerecord.Page;
/**
* 本 demo 仅表达最为粗浅的 jfinal 用法,更为有价值的实用的企业级用法
* 详见 JFinal 俱乐部: http://jfinal.com/club
*
* BlogService
* 所有 sql 与业务逻辑写在 Service 中,不要放在 Model 中,更不
* 要放在 Controller 中,养成好习惯,有利于大型项目的开发与维护
*/
public class StudentService {
/**
* 所有的 dao 对象也放在 Service 中,并且声明为 private,避免 sql 满天飞
* sql 只放在业务层,或者放在外部 sql 模板,用模板引擎管理:
* http://www.jfinal.com/doc/5-13
*/
private Student dao = new Student().dao();
public Page<Student> paginate(int pageNumber, int pageSize) {
return dao.paginate(pageNumber, pageSize, "select *", "from student order by id asc");
}
public Student findById(int id) {
return dao.findById(id);
}
public void deleteById(int id) {
dao.deleteById(id);
}
}