JFinal極速開發(fā)框架使用筆記分享
記錄第一次使用JFinal,從簡(jiǎn)單的框架搭建到增刪改查,從自帶的方法到正常框架習(xí)慣的使用方式。
JFinal官網(wǎng):http://www.jfinal.com/
JFinal 是基于 Java 語(yǔ)言的極速 WEB + ORM 框架,其核心設(shè)計(jì)目標(biāo)是開發(fā)迅速、代碼量少、學(xué)習(xí)簡(jiǎn)單、功能強(qiáng)大、輕量級(jí)、易擴(kuò)展、Restful。在擁有Java語(yǔ)言所有優(yōu)勢(shì)的同時(shí)再擁有ruby、python、php等動(dòng)態(tài)語(yǔ)言的開發(fā)效率。
JFinal有如下主要特點(diǎn):
MVC架構(gòu),設(shè)計(jì)精巧,使用簡(jiǎn)單
遵循COC原則,零配置,無(wú)xml
獨(dú)創(chuàng)Db + Record模式,靈活便利
ActiveRecord支持,使數(shù)據(jù)庫(kù)開發(fā)極致快速
自動(dòng)加載修改后的java文件,開發(fā)過(guò)程中無(wú)需重啟web server
AOP支持,攔截器配置靈活,功能強(qiáng)大
Plugin體系結(jié)構(gòu),擴(kuò)展性強(qiáng)
多視圖支持,支持FreeMarker、JSP、Velocity
強(qiáng)大的Validator后端校驗(yàn)功能
功能齊全,擁有struts2的絕大部分功能
體積小僅632K,且無(wú)第三方依賴
例子:
本人用的maven,首先創(chuàng)建一個(gè)maven項(xiàng)目:

我的項(xiàng)目創(chuàng)建之后首先要設(shè)置:


然后點(diǎn)Apply
還有其他一些設(shè)置等等,我的問(wèn)題,這里先跳過(guò)
然后在pom.xml中引入jar包:
maven搜索jar包:http://mvnrepository.com/
官方demo的pom.xml:
這里沒有引入json,我的這個(gè)demo最后的方法需要json
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.demo</groupId>
<artifactId>jfinal_demo_for_maven</artifactId>
<packaging>war</packaging>
<version>3.2</version>
<name>jfinal_demo_for_maven Maven Webapp</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
</properties>
<!-- 使用阿里 maven 庫(kù) -->
<repositories>
<repository>
<id>ali-maven</id>
<url>http://maven.aliyun.com/nexus/content/groups/public</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
<updatePolicy>always</updatePolicy>
<checksumPolicy>fail</checksumPolicy>
</snapshots>
</repository>
</repositories>
<!-- 添加快照版本庫(kù),updatePolicy: always、daily、interval、never -->
<!-- repositories>
<repository>
<id>sonatype-nexus-snapshots</id>
<name>Sonatype Nexus Snapshots</name>
<url>https://oss.sonatype.org/content/repositories/snapshots/</url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
<updatePolicy>daily</updatePolicy>
</snapshots>
</repository>
</repositories -->
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.jfinal</groupId>
<artifactId>jetty-server</artifactId>
<version>8.1.8</version>
<!--
此處的 scope 值為 compile 僅為支持 IDEA 下啟動(dòng)項(xiàng)目
打 war 包時(shí)需要改成 provided,以免將一些無(wú)用的 jar 打進(jìn)去
-->
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.jfinal</groupId>
<artifactId>jfinal</artifactId>
<version>3.3</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.16</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.44</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.29</version>
</dependency>
<dependency>
<groupId>com.jfinal</groupId>
<artifactId>cos</artifactId>
<version>2017.5</version>
</dependency>
</dependencies>
<build>
<finalName>jfinal_demo_for_maven</finalName>
<plugins>
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>8.1.8.v20121106</version>
<configuration>
<stopKey>stop</stopKey>
<stopPort>5599</stopPort>
<webAppConfig>
<contextPath>/</contextPath>
</webAppConfig>
<scanIntervalSeconds>5</scanIntervalSeconds>
<connectors>
<connector implementation="org.eclipse.jetty.server.nio.SelectChannelConnector">
<port>80</port>
<maxIdleTime>60000</maxIdleTime>
</connector>
</connectors>
</configuration>
</plugin>
</plugins>
</build>
</project>
然后是web.xml的配置:
注意:
DemoConfig.java 文件所在的包以及自身文件名必須與 web.xml 中的 param-value 標(biāo)簽內(nèi)的配置相一致(在本例中該配置為 demo.DemoConfig)。
<filter> <filter-name>jfinal</filter-name> <filter-class>com.jfinal.core.JFinalFilter</filter-class> <init-param> <param-name>configClass</param-name> <param-value>demo.DemoConfig</param-value> </init-param> </filter> <filter-mapping> <filter-name>jfinal</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
接下來(lái)創(chuàng)建java文件:
創(chuàng)建DemoConfig并繼承JFinalConfig,DemoConfig是主文件,運(yùn)行這個(gè)文件啟動(dòng)項(xiàng)目,就像運(yùn)行普通java文件main一樣,同時(shí)運(yùn)行之后如果修改其他代碼,并不需要重啟,框架會(huì)自動(dòng)修改,直接刷新就可以看到修改后的內(nèi)容。
這是初始的簡(jiǎn)單的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 就可以看到頁(yè)面輸出了 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);
//此方法用來(lái)配置 JFinal 常量值,如開發(fā)模式常量 devMode 的配置,如下代碼配置了 JFinal
//運(yùn)行在開發(fā)模式:在開發(fā)模式下,JFinal 會(huì)對(duì)每次請(qǐng)求輸出報(bào)告,如輸出本次請(qǐng)求的 URL、Controller、Method
//以及請(qǐng)求所攜帶的參數(shù)。
}
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);
// 此方法用來(lái)配置JFinal的Plugin,如下代碼配置了Druid數(shù)據(jù)庫(kù)連接池插件與ActiveRecord
// 數(shù)據(jù)庫(kù)訪問(wèn)插件。通過(guò)以下的配置,可以在應(yīng)用中使用 ActiveRecord 非常方便地操作數(shù)據(jù)庫(kù)。
}
public void configInterceptor(Interceptors me) {
//me.add(new AuthInterceptor());
// 此方法用來(lái)配置 JFinal 的全局?jǐn)r截器,全局?jǐn)r截器將攔截所有 action 請(qǐng)求,除非使用
// @Clear 在 Controller 中清除,如下代碼配置了名為 AuthInterceptor 的攔截器。
}
public void configHandler(Handlers me) {
}
}
這里面各個(gè)方法的簡(jiǎn)單說(shuō)明都寫在注釋里了。
然后是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那里有多種方法,這個(gè)要和前臺(tái)傳參寫法一致,Controller 提供了 getPara 系列方法,官網(wǎng)api里很詳細(xì)
jfinal用的是原生態(tài)sql語(yǔ)句,簡(jiǎn)單,方便,setAttr("studentList", list);把結(jié)果集放到request范圍里,
jfinal也有直接獲取表單里分裝成對(duì)象的方法 getModel(Student.class);就是,和struts2一樣,表單name對(duì)應(yīng)上就可以了,非常方便
添加那里對(duì)于oracle用序列維護(hù)studentid student.set("studentid", "mysequence.nextval").save(); jfinal有多種返回方式,也可以返回json數(shù)據(jù),render 系列方法,官網(wǎng)api里很詳細(xì)
*/
static StudentService service = new StudentService();
@Before(StudentInterceptor.class)
public void index() {
List<Student> list = Student.dao.find("select * from student");
setAttr("studentList", list);
//注意下面路徑的的前面如果帶/則從根目錄下開始找,也就是說(shuō) 下代碼 = render("/student/index.html");
render("index.html");
}
public void add() {
render("add.html");
}
public void test() {
List<Student> list = Student.dao.find("select * from student");
setAttr("studentList", list);
setAttr("student", list.get(0));
render("test.jsp");
}
public void getlist() {
List<Student> 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<Student> 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請(qǐng)求中第一個(gè)值
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用來(lái)接收頁(yè)面表單域傳遞過(guò)來(lái)的model對(duì)象,表單域名稱以”modelName.attrName”
http://www.jfinal.com
方式命名,getModel 使用的 attrName 必須與數(shù)據(jù)表字段名完全一樣。
getBean 方法用于支持傳統(tǒng) Java Bean,包括支持使用 jfnal 生成器生成了 getter、setter 方法
的 Model,頁(yè)面表單傳參時(shí)使用與 setter 方法相一致的 attrName,而非數(shù)據(jù)表字段名。
getModel與getBean區(qū)別在于前者使用數(shù)表字段名而后者使用與setter方法一致的屬性名進(jìn)
行數(shù)據(jù)注入。建議優(yōu)先使用 getBean 方法。
*/
//getBean(Student.class).save();
getModel(Student.class).save();
redirect("/student");
}
@Before(StudentValidator2.class)
public void savebean() {
getBean(Student.class).save();
redirect("/student");
}
}
同樣的簡(jiǎn)單的說(shuō)明也寫在注釋里了。
方法基本上都在這里了,下面是其他的一些配置:
這是實(shí)體類:
package demo.model;
import com.jfinal.plugin.activerecord.Model;
public class Student extends Model<Student> {
public static final Student dao = new Student();
/**
* ActiveRecord 是 jfinal 最核心的組成部分之一,通過(guò) ActiveRecord 來(lái)操作數(shù)據(jù)庫(kù),將極大地減少代碼量,極大地提升開發(fā)效率,配置在后面,我這里用的是Model,Model 是 ActiveRecord 中最重要的組件之一,它充當(dāng) MVC 模式中的 Model部分。
以上代碼中的 User 通過(guò)繼承 Model,便立即擁有的眾多方便的操作數(shù)據(jù)庫(kù)的方法。在 User 中聲明的 dao 靜態(tài)對(duì)象是為了方便查詢操作而定義的,該對(duì)象并不是必須的。 基于ActiveRecord 的 Model 無(wú)需定義屬性, 無(wú)需定義 getter、 setter方法,無(wú)需 XML 配置,無(wú)需 Annotation 配置,極大降低了代碼量。Model常見方法見官方API。
JFinal還有 獨(dú)創(chuàng) Db + Record 模式,Db 類及其配套的 Record 類, 提供了在 Model 類之外更為豐富的數(shù)據(jù)庫(kù)操作功能。使用 Db 與 Record 類時(shí),無(wú)需對(duì)數(shù)據(jù)庫(kù)表進(jìn)行映射,Record 相當(dāng)于一個(gè)通用的 Model。Db常見方法見官方API。
*/
}
StudentValidator:
package StudentValidator;
import com.jfinal.core.Controller;
import com.jfinal.validate.Validator;
public class StudentValidator extends Validator {
//在校驗(yàn)失敗時(shí)才會(huì)調(diào)用
@Override
protected void handleError(Controller controller) {
controller.keepPara("student.studentname");//將提交的值再傳回頁(yè)面以便保持原先輸入的值
controller.render("/add.html");
}
@Override
protected void validate(Controller controller) {
//驗(yàn)證表單域name,返回信息key,返回信息value
validateRequiredString("student.studentname", "studentnameMsg",
"請(qǐng)輸入學(xué)生名稱!");
}
}
package StudentValidator;
import com.jfinal.core.Controller;
import com.jfinal.validate.Validator;
public class StudentValidator2 extends Validator {
//在校驗(yàn)失敗時(shí)才會(huì)調(diào)用
@Override
protected void handleError(Controller controller) {
controller.keepPara("studentname");//將提交的值再傳回頁(yè)面以便保持原先輸入的值
controller.render("/add.html");
}
@Override
protected void validate(Controller controller) {
//驗(yàn)證表單域name,返回信息key,返回信息value
validateRequiredString("studentname", "studentnameMsg",
"請(qǐng)輸入學(xué)生名稱!");
}
}
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");
}
}
然后是前臺(tái)的顯示頁(yè)面:
關(guān)于前臺(tái)頁(yè)面,需要看一下文檔第六章,JFinal模板引擎的內(nèi)容,了解JFinal如何在前臺(tái)顯示,這是很重要的
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>學(xué)生管理</title>
<script type="text/javascript" src="/jquery-1.12.4.min.js"></script>
</head>
<body>
<h1><a href="/student/jsp">學(xué)生管理</a></h1>
<a href="/student/layui">測(cè)試layui</a>
<a href="/student/test">編輯索引0</a><br>
<a href="/student/add">添加</a><br>
<form action="/student/get">
id:<input type="text" name="studentid">
<input type="submit" value="查詢">
</form>
<a href="/student/delete">刪除</a>
<form action="/student/delete">
id:<input type="text" name="studentid">
<input type="submit" value="刪除">
</form>
#for(x : [1..10])
#(x)
#end
<table id="listtable" border="1">
<tbody>
<tr>
<th>id</th>
<th>姓名</th>
<th>性別</th>
<th>年齡</th>
<th>地址</th>
<th>郵箱</th>
<th>操作</th>
</tr>
#for(x : studentList)
<tr>
<td style="text-align:left;">#(x.studentid)</td>
<td style="text-align:left;">#(x.studentname)</td>
<td style="text-align:left;">#(x.sex)</td>
<td style="text-align:left;">#(x.age)</td>
<td style="text-align:left;">#(x.address)</td>
<td style="text-align:left;">#(x.email)</td>
<td style="text-align:left;">
<a href="/student/delete?studentid=#(x.studentid)">刪除</a>
<a href="/student/delete1/#(x.studentid)">刪除</a>
<a href="/student/get?studentid=#(x.studentid)">修改</a>
<a href="/student/get1/#(x.studentid)">修改1</a>
</td>
</tr>
#end
</tbody>
</table>
</body>
</html>

這就是頁(yè)面效果,因?yàn)闆]有樣式所以看起來(lái)比較粗狂,然后下面是用正常使用的layui,加上正常習(xí)慣的方法返回?cái)?shù)據(jù)組成的:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>學(xué)生管理layui</title>
<script type="text/javascript" src="/layui-v2.2.45/layui/layui.js"></script>
<link rel="stylesheet" href="/layui-v2.2.45/layui/css/layui.css" media="all">
</head>
<body>
<div style="margin: 0px; background-color: white; margin: 0 10px;">
<blockquote class="layui-elem-quote">
<a href="/student/add"><button type="button" id="usersAdd_btn"
class="layui-btn layui-btn-small">
<i class="fa fa-plus" aria-hidden="true"></i> 添加
</button></a>
<form class="layui-form" style="float: right;"
onsubmit="return false">
<div class="layui-form-item" style="margin: 0;">
<div class="demoTable">
搜索用戶:
<div class="layui-inline">
<input class="layui-input" name="name" id="demoReload"
autocomplete="off">
</div>
<button class="layui-btn" style="transform: translateY(-3px);"
data-type="reload">搜索</button>
</div>
</div>
</form>
</blockquote>
</div>
<table class="layui-table"
lay-data="{url:'/student/getlist',id:'idTest',height: 'full-60' ,}"
lay-filter="demo">
<thead>
<tr>
<th lay-data="{field:'studentid', width:'20%',}">id</th>
<th lay-data="{field:'studentname', width:'20%'}">姓名</th>
<th lay-data="{field:'sex', width:'20%'}">性別</th>
<th lay-data="{field:'age', width:'20%'}">年齡</th>
<th lay-data="{field:'address', width:'20%'}">地址</th>
<th lay-data="{fixed: 'right', width:'17%', align:'center', toolbar: '#barDemo1'}"></th>
</tr>
</thead>
</table>
<script type="text/html" id="barDemo1">
<a class="layui-btn layui-btn-xs" id="edit" lay-event="edit">修改</a>
<a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del">刪除</a>
</script>
</body>
<script>
layui.use('table', function(){
var table = layui.table,
form = layui.form;;
//監(jiān)聽表格復(fù)選框選擇
table.on('checkbox(demo)', function(obj){
console.log(obj)
});
//監(jiān)聽工具條
table.on('tool(demo)', function(obj){
var data = obj.data;
if(obj.event === 'del'){
layer.confirm('真的刪除用戶嗎', function(index){
$.ajax({
type:"post",
url:"/student/delete?studentid="+data.studentid,
dataType:"text",//返回的
success:function(returndata) {
table.reload("idTest");
},
error:function(msg) {
console.log(msg);
}
});
});
} else if(obj.event === 'edit'){
var index = layui.layer.open({
title : "修改",
type : 2,
area: ['380px', '80%'],
content : "/student/get?studentid="+data.studentid,
cancel: function(index, layero){
layer.close(index);
table.reload("idTest");
}
})
//改變窗口大小時(shí),重置彈窗的高度,防止超出可視區(qū)域(如F12調(diào)出debug的操作)
$(window).resize(function(){
layui.layer.full(index);
})
layui.layer.full(index);
}else if(obj.event === 'detail'){
layer.confirm('確定通過(guò)該用戶嗎', function(index){
$.ajax({
type:"post",
url:"<%=basePath%>/sys/user/passuser",
data:{id:data.id},
//dataType:"text",//返回的
success:function(returndata) {
layui.use('layer', function() {
layer.msg(returndata.msg);
});
table.reload('idTest', {
page: {
curr: 1 //重新從第 1 頁(yè)開始
},
});
},
error:function(msg) {
console.log(msg);
}
});
});
}
});
var $ = layui.$, active = {
getCheckData: function(){ //獲取選中數(shù)據(jù)
var checkStatus = table.checkStatus('idTest'),
data = checkStatus.data;
layer.alert(JSON.stringify(data));
}
,getCheckLength: function(){ //獲取選中數(shù)目
var checkStatus = table.checkStatus('idTest')
,data = checkStatus.data;
layer.msg('選中了:'+ data.length + ' 個(gè)');
}
,isAll: function(){ //驗(yàn)證是否全選
var checkStatus = table.checkStatus('idTest');
layer.msg(checkStatus.isAll ? '全選': '未全選')
}
};
$('.demoTable .layui-btn').on('click', function(){
var type = $(this).data('type');
active[type] ? active[type].call(this) : '';
});
});
</script>
</html>
這樣感覺稍微好了一點(diǎn),因?yàn)橹皇堑谝淮问褂茫鲆粋€(gè)測(cè)試,所以還是比較粗獷的。
然后需要注意的是這種方式的數(shù)據(jù)返回的問(wèn)題:
public void getlist() {
List<Student> 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數(shù)據(jù)用renderJson的方式返回。
然后需要 注意的是,我嘗試過(guò)直接返回list集合,貌似方法是可行的,只是因?yàn)閘ayui表格必須是以上格式才能接收數(shù)據(jù)所以沒有顯示到頁(yè)面上,但是當(dāng)我直接return jo的時(shí)候后臺(tái)報(bào)錯(cuò),這個(gè)問(wèn)題只能等明天在學(xué)習(xí)并解決了。
以下是返回的render方法的幾種使用方式:


然后需要注意的是方法的調(diào)用和傳參:
如下兩種方法和傳參的方式:
<a href="/student/delete?studentid=#(x.studentid)">刪除</a>
<a href="/student/delete1/#(x.studentid)">刪除</a>
<a href="/student/get?studentid=#(x.studentid)">修改</a>
<a href="/student/get1/#(x.studentid)">修改1</a>
下面是controller方法:
public void delete() {
// 獲取表單域名為studentid的值
Student.dao.deleteById(getPara("studentid"));
forwardAction("/student");
}
public void delete1() {
// 獲取url請(qǐng)求中第一個(gè)值
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");
}
最后就是添加接受實(shí)體類的兩種方式:
@Before(StudentValidator.class)
public void save() {
/**
* getModel用來(lái)接收頁(yè)面表單域傳遞過(guò)來(lái)的model對(duì)象,表單域名稱以”modelName.attrName”
http://www.jfinal.com
方式命名,getModel 使用的 attrName 必須與數(shù)據(jù)表字段名完全一樣。
getBean 方法用于支持傳統(tǒng) Java Bean,包括支持使用 jfnal 生成器生成了 getter、setter 方法
的 Model,頁(yè)面表單傳參時(shí)使用與 setter 方法相一致的 attrName,而非數(shù)據(jù)表字段名。
getModel與getBean區(qū)別在于前者使用數(shù)表字段名而后者使用與setter方法一致的屬性名進(jìn)
行數(shù)據(jù)注入。建議優(yōu)先使用 getBean 方法。
*/
//getBean(Student.class).save();
getModel(Student.class).save();
redirect("/student");
}
@Before(StudentValidator2.class)
public void savebean() {
getBean(Student.class).save();
redirect("/student");
}
其中第二中的getBean方式在我這個(gè)demo中,可能由于沒有設(shè)置getset的原因,添加之后是只有生成了ID,沒有其他數(shù)據(jù)的。
如果需要使用。下面是官方demo的寫法:
package com.demo.common.model;
import com.demo.common.model.base.BaseBlog;
/**
* 本 demo 僅表達(dá)最為粗淺的 jfinal 用法,更為有價(jià)值的實(shí)用的企業(yè)級(jí)用法
* 詳見 JFinal 俱樂部: http://jfinal.com/club
*
* Blog model.
* 數(shù)據(jù)庫(kù)字段名建議使用駝峰命名規(guī)則,便于與 java 代碼保持一致,如字段名: userId
*/
@SuppressWarnings("serial")
public class Blog extends BaseBlog<Blog> {
}
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<M extends BaseBlog<M>> extends Model<M> 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");
}
}
以上這篇JFinal極速開發(fā)框架使用筆記分享就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
- JFinal使用ajaxfileupload實(shí)現(xiàn)圖片上傳及預(yù)覽
- JFinal實(shí)現(xiàn)偽靜態(tài)的方法
- jfinal與bootstrap的登出實(shí)戰(zhàn)詳解
- java 中JFinal getModel方法和數(shù)據(jù)庫(kù)使用出現(xiàn)問(wèn)題解決辦法
- Bootstrap+jfinal退出系統(tǒng)彈出確認(rèn)框的實(shí)現(xiàn)方法
- Bootstrap+jfinal實(shí)現(xiàn)省市級(jí)聯(lián)下拉菜單
- jfinal與bootstrap的登錄跳轉(zhuǎn)實(shí)戰(zhàn)演習(xí)
- jfinal添加jcaptcha驗(yàn)證碼實(shí)現(xiàn)方法
- Java中JFinal框架動(dòng)態(tài)切換數(shù)據(jù)庫(kù)的方法
相關(guān)文章
使用Java實(shí)現(xiàn)獲取excel附件并解析
在Java中,我們經(jīng)常需要讀取Excel文件中的數(shù)據(jù),進(jìn)行處理和分析,本文將介紹如何使用Java代碼來(lái)獲取與解析Excel文件中的附件,希望對(duì)大家有所幫助2025-04-04
java多線程處理執(zhí)行solr創(chuàng)建索引示例
這篇文章主要介紹了java多線程處理執(zhí)行solr創(chuàng)建索引示例,需要的朋友可以參考下2014-02-02
java源碼解析之String類的compareTo(String otherString)方法
這篇文章主要給大家介紹了關(guān)于java源碼解析之String類的compareTo(String otherString)方法的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2018-09-09
SpringBoot采用AJAX實(shí)現(xiàn)異步發(fā)布帖子詳解
Ajax是一種web應(yīng)用技術(shù),可以借助客戶端腳本(javascript)與服務(wù)端應(yīng)用進(jìn)行異步通訊,獲取服務(wù)端數(shù)據(jù)以后,可以進(jìn)行局部刷新,進(jìn)而提高數(shù)據(jù)的響應(yīng)和渲染速度。所有的Ajax請(qǐng)求都會(huì)基于DOM(HTML元素)事件,通過(guò)XHR(XMLHttpRequest)對(duì)象實(shí)現(xiàn)與服務(wù)端異步通訊局部更新2022-08-08
Spring Boot @Scheduled定時(shí)任務(wù)代碼實(shí)例解析
這篇文章主要介紹了Spring Boot @Scheduled定時(shí)任務(wù)代碼實(shí)例解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-06-06
java 集合之實(shí)現(xiàn)類ArrayList和LinkedList的方法
下面小編就為大家?guī)?lái)一篇java 集合之實(shí)現(xiàn)類ArrayList和LinkedList的方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-10-10
java運(yùn)行windows的cmd命令簡(jiǎn)單代碼
這篇文章主要介紹了java運(yùn)行windows的cmd命令簡(jiǎn)單代碼,有需要的朋友可以參考一下2013-12-12
Java7和Java8中的ConcurrentHashMap原理解析
這篇文章主要介紹了Java7和Java8中的ConcurrentHashMap原理解析,對(duì)ConcurrentHashMap感興趣的讀者,一定要好好看一下2021-04-04

