jfinal 是一个orm框架,但是在用他的时候你不用写任何配置,或者说想写的话可以写一个数据源的配置文件如果不想写的话那真的什么都不用写,真有这么神奇我们来看看!
首先来个工程的目录结构:
ok 从传递的文件中我们能看到所有的文件,简单的说一下有哪些文件,每个文件的作用是什么:
1、web.xml 配置文件这里面配置了jfinal的拦截器,拦截器的作用就是将请求指向了一个JFinalConfig类。
2、datasource.properties 数据源配置文件,这个可以配置也可以不配置。
3、WebContent 下的view 目录下都是前端的jsp文件。
4、chm/model 下的User类,这个类的继承了Jfinal的Model<User> 这个类,也就是对象模型对应的bean但是这里不定义属性。
5、chm/init 下的ProjectConfig 类继承了JFinalConfig 这个类并重写了JFinalConfig 的方法。
6、chm/controller下的UserController 就是请求的具体处理以及返回前端的处理。
简单看了文件结构后我们来看看代码:
1、web.xml 配置文件
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> <filter> <filter-name>jfinal</filter-name> <filter-class>com.jfinal.core.JFinalFilter</filter-class> <init-param> <param-name>configClass</param-name> <!--处理请求的具体类 --> <param-value>chm.init.ProjectConfig</param-value> </init-param> </filter> <filter-mapping> <filter-name>jfinal</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </web-app>
2、ProjectConfig.java 类继承了JFinalConfig 类
package chm.init; import chm.controller.UserController; import chm.model.User; 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.plugin.activerecord.ActiveRecordPlugin; import com.jfinal.plugin.c3p0.C3p0Plugin; import com.jfinal.render.ViewType; /** * @author WHD data 2016年3月12日 */ public class ProjectConfig extends JFinalConfig { @Override public void configConstant(Constants me) { // 加载少量必要配置,随后可用getProperty(...)获取值 loadPropertyFile("datasource.properties"); me.setDevMode(getPropertyToBoolean("devMode", false)); // 视图的配置jsp me.setViewType(ViewType.JSP); } @Override public void configRoute(Routes me) { // 请求路径的配置当请求/user 时对应到UserController控制层的index方法(默认) // 如果要调用UserController层的其他方法要在请求路径中指定方法名称 me.add("/user", UserController.class); // 请求路径 } @Override public void configPlugin(Plugins me) { // jfinal 插件配置 // 配置C3p0数据库连接池插件 C3p0Plugin c3p0Plugin = new C3p0Plugin(getProperty("jdbcUrl"), getProperty("user"), getProperty("password").trim(), "com.mysql.jdbc.Driver"); me.add(c3p0Plugin); // 配置ActiveRecord插件 ActiveRecordPlugin arp = new ActiveRecordPlugin(c3p0Plugin); me.add(arp); arp.addMapping("user_table", User.class); // 映射blog 表到 Blog模型 } @Override public void configInterceptor(Interceptors me) { // TODO Auto-generated method stub } @Override public void configHandler(Handlers me) { // TODO Auto-generated method stub } }
3、UserController 类继承了jfinal的Controller类
package chm.controller; import java.util.List; import chm.model.User; import com.jfinal.core.Controller; import com.jfinal.plugin.activerecord.Page; /** * @author WHD data 2016年3月12日 */ public class UserController extends Controller { // 默认访问index方法所以不能再同一个controller中定义两个index方法 public void index() { System.out.println("index 参数"); // getPara getPara(1) getPara("age") // getParaToInt()都是获取参数的方法jfinal支持restful规则 // 参数获取规则具体见jfinal手册 String a = getPara(0); String b = getPara(1); String c = getPara(); String age = getPara("age"); System.out.println("a:" + a); System.out.println("b: " + b); System.out.println("c:" + c); System.out.println("age:" + age); // 分页获取数据 Page<User> userPages = User.dao.paginate(1, 10, "select *", "from user_table order by id asc"); // jfinal 的sql是原生的,平时怎么写就怎么写 List<User> list = User.dao.find("select * from user_table limit 1,3"); System.out.println("list.size: " + list.size()); // 这里的setAttribute是HttpServletRequest 对象的setAttribute方法 setAttr("userList", userPages.getList()); setAttr("list", list); // 返回到指定前端,这个和springmvc的返回和展示或者说和HttpServlet一样的 render("/view/user.jsp"); } // 添加方法 public void add() { System.out.println("新增"); // 这种方法的话前端定义的名称要和数据库中表的字段要一致,不然的不行,这个有点像springmvc pojo方法获取参数的方式 getModel(User.class).save(); // 第二种添加方法 String name = getPara("user.userName"); String password = getPara("user.password"); System.out.println("name:" + name + " password: " + password); // 创建对象,设置属性调用对象的save方法保存到对应的数据库表中 boolean b = new User().set("userName", name).set("password", password) .save(); System.out.println("b: " + b); // user就是配置文件中配置的/user 这里也就是方法index方法 redirect("/user"); } // 按照id删除 public void delete() { // 获取参数id并将参数转化为int型,在调用删除方法进行删除 User.dao.deleteById(getParaToInt()); redirect("/user"); } // 编辑 public void edit() { // 获取编辑的id并进行查询在将获取的参数值并设置到request对象的setAttribute方法 setAttr("user", User.dao.findById(getParaToInt())); // 返回到指定的jsp页面 render("/view/userEdit.jsp"); } // 更新方法 public void update() { // getModel(User.class).update(); String id = getPara("user.id"); String name = getPara("user.userName"); String password = getPara("user.password"); System.out.println("update id: " + id + " name: " + name + " password: " + password); // 更新的方法先获取id为id的user对象在设置改变的值最后更新数据库 new User().findById(id).set("userName", name).set("password", password) .update(); redirect("/user"); } }
4、User.java 类 继承了Model<User> 类
package chm.model; import com.jfinal.plugin.activerecord.Model; /** * @author WHD data 2016年3月12日 */ public class User extends Model<User> { /** * */ private static final long serialVersionUID = -6465542910996567778L; public static final User dao = new User(); }
上面的四个配置文件可以说是从请求开始到返回数据的整个流程,但是数据前台怎么展示那,下面来看看user.jsp
5、user.jsp
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <!DOCTYPE html> <html> <body> <a href="/jfinal/view/userAdd.jsp" class="btn btn-primary btn-sm"> 新增用户 </a> <table> <c:forEach var="user" items="${userList}"> <tr> <td><c:out value="${user.id}" default="" /></td> <td>${user.userName}</td> <td>${user.password}</td> <td> <a href="/jfinal/user/delete/${user.id}">删除</a> <a href="/jfinal/user/edit/${user.id}">修改</a></td> </tr> </c:forEach> <!--controller 用两种方式获取数据并进行展示 --> <c:forEach var="users" items="${list}"> <tr> <td><c:out value="${users.id}" default="" /></td> <td>${users.userName}</td> <td>${users.password}</td> <td> <a href="/jfinal/user/delete/${users.id}">删除</a> <a href="/jfinal/user/edit/${users.id}">修改</a></td> </tr> </c:forEach> </table> </body> </html>
6、datasource.properties配置文件,在前面说了jfinal是零配置所以这个配置不是必须的
jdbcUrl = jdbc:mysql://127.0.0.1/chm?characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull user = root password =admin devMode = true
ok到这里我们所有的代码都有了,也就是一个流程都有了,下面我们来看看整个流程是什么,而具体的处理细节不在这里啰嗦了因为代码中有很多注释
这是web 项目所以web.xml 是必须配置的,而从上面的文件中我们看到这个配置文件中配置了jfinal的过滤器,而过滤器所指向的就是我们定义的配置文件,所以所有的请求都会先到配置类中的configRoute() 这个方法中去找对应的路径,而同过上面的文件我们发现每一个路径对应着一个Class 实例这里的class实例就是 一个继承了Controller的类,这样的话就会把这个请求重定向到Controller类的具体方法上,这里注意如果在请求路径中不指定方法名的话会默认调用控制层的index() 方法来处理。ok 到这里一个请求就到了想要到的地方。之后就是从请求路径中获取数据,获取数据的方法可以看上面的代码也可以看文档,获取参数后我们按照参数去数据库查询。
这里要特别说以下查询的事情,jfinal的查询特别方便你可以直接调用model下定义的那个类的User 类型的dao 的方法去获取数据,获取后的数据就是一个个的user对象你可以调用jfinal 的model 提供的方法来获取一个对象的各个属性的值。
将获取的一个对象获一个对象集合设置到request 中,而在jfinal 中可以直接调用setAttr("list", list);方法来将集合添加到request中。
ok数据获取了,也添加到request对象中了,剩下的就是返回,jfinal 支持 jsp freemark json text html 等等前端解析器所以这里使用的是jsp 返回调用了render("/view/user.jsp"); 来返回到指定的页面,具体展示看之前的代码。
过程描述到此结束,明天话一个请求的时序图