JFinal 是基於 Java 語言的極速 WEB + ORM 框架,其核心設計目標是開發迅速、代碼量少、學習簡單、功能強大、輕量級、易擴展、Restful。在擁有Java語言全部優點的同時再擁有ruby、python、php等動態語言的開發效率!php
簡單來講,Jfinal是一套基於微內核的快速開發框架。給開發者提供更高效、易用的工具框架。css
Ps:開源Jfinal項目詳情,點擊這裏進入html
寫這篇博客的目的呢,其實很簡單。前端
其一:官方的文檔不具連貫性,都是某某API的用法和介紹,小白的話讀了文檔可能仍是兩臉懵逼😂(其實筆者就是這個小白);俗話說紙上得來終覺淺嘛,因此本身有思路之後但願寫一篇以 用戶註冊功能 爲需求的Jfinal的搭建、入門、和簡單的開發流程的一個教程;但願能夠幫到像我同樣的孩紙。java
其二:於本身來講是一個總結,能夠用做爲一個初步掌握Jfinal的視角去從新的審視本身的學習過程。python
其三:裝個X嘛🤪mysql
好了,前面廢話了那麼多。對Jfinal有了初步的瞭解後,下面我們開幹吧:(開發環境爲:IDEA For Mac,項目管理工具使用Maven)jquery
1. 首先,使用maven建立一個web項目,如圖:git
在pom.xml中添加jar包依賴,其中jfinal相關的兩個是必須的,junit做爲單元測試,最後兩個用來鏈接數據庫web
<dependencies> <!--單元測試Junit--> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> <!-- Jfinal相關(jfinal、jetty-server) --> <dependency> <groupId>com.jfinal</groupId> <artifactId>jfinal</artifactId> <version>3.3</version> </dependency> <dependency> <groupId>com.jfinal</groupId> <artifactId>jetty-server</artifactId> <version>8.1.8</version> </dependency> <!--阿里的數據庫鏈接池--> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.6</version> </dependency> <!-- mysql的鏈接驅動 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.18</version> </dependency> </dependencies>
配置完成後,咱們還須要更改下項目的目錄結構而後 再來使用jfinal。
更改完成後,如圖:
2.項目建立完成,接下來咱們來引入Jfinal。
首先,在package下建一個jfinal_config子包,而後建立一個類AppConfig來繼承JFinalConfig類來完成初步設置,以下:
public class AppConfig extends JFinalConfig { @Override public void configConstant(Constants constants) { } @Override public void configRoute(Routes routes) { } @Override public void configPlugin(Plugins plugins) { } @Override public void configEngine(Engine engine) { } @Override public void configInterceptor(Interceptors interceptors) { } @Override public void configHandler(Handlers handlers) { } }
繼承JFinalConfig類須要重寫這七個方法,具體方法意義,自行參考文檔,貼圖簡示
設置開發模式
設置路由
設置插件
3. 而後,咱們在package下再新建一個子包controller,在controller包下新建RegisterController類繼承Controller,以下:
public class RegisterController extends Controller { /** * index方法爲 未指定具體方法層面的接口時 默認訪問的方法 * */ public void index(){ //返回一個視圖 render("register.jsp"); } /** * 註冊表單提交接口 */ public void addUser(){ } }
寫完controller,咱們須要配置路由使得用戶能夠經過url來映射到咱們對應的controller,在此以前咱們先要在WEB-INF下新建一個文件夾views做爲前端視圖的根目錄。
而後在views下新建一個register.jsp來展現咱們的註冊頁. 完成後 以下:
這裏的jsp名稱,要與咱們controller的index方法 返回的視圖名稱相一致。
以上的操做完成後,咱們去AppConfig中配置一下路由映射
具體的路由用法,你們參考官方文檔,本篇主要闡述宏觀的思路。
3. 接下來,在web.xml中配置下咱們的自定義的Config。
4. 而後,咱們在AppConfig中添加main方法來啓動項目、測試 :
打開瀏覽器,輸入localhost:8088測試(😅 不會前端,因此現學了一下,作的很差看,輕噴)
5. ORM層配置
具體操做因業務/狀況而定,個人配置以下:
這是model層的User類,對應數據庫的user表
這是 db.properties
jdbcUrl=jdbc:mysql://localhost:3306/JfinalDemoDB?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull username=root password=admin showSql=true
在configConstant()方法中默認讀取db.properties文件
而後在configPlugin()方法中 使用數據庫相關組件:
@Override public void configPlugin(Plugins plugins) { //經過讀取db.properties來初始化druid插件 DruidPlugin druidPlugin = new DruidPlugin(getProperty("jdbcUrl"),getProperty("username"), getProperty("password")); //添加該插件 plugins.add(druidPlugin); //將該插件做爲使用的 持久層框架 ActiveRecordPlugin activeRecordPlugin = new ActiveRecordPlugin(druidPlugin); activeRecordPlugin.addMapping("user",User.class).setShowSql(Boolean.parseBoolean(getProperty( "showSql" ))); plugins.add(activeRecordPlugin); }
在package下新建一個test子包,測試orm層配置是否生效。
測試發現,報空指針異常,那麼經過檢查,應該是orm層插件在junit環境下不能生效,因此咱們採用手動配置數據庫插件方式來實現 junit 的orm層的單元測試。
在package下新建一個utils子包,而後在utils中新建一個類ManualOrmMap 來配置相關參數。(其實就是把 AppConfig的configPlugin()中的配置單獨拿出來)
************這是個大坑*********** 代碼以下:
public class ManualOrmMap { protected static DruidPlugin dp; protected static ActiveRecordPlugin arp = null; @BeforeAll static void initAll(){ if(dp==null){ PropKit.use("db.properties"); dp = new DruidPlugin(PropKit.get("jdbcUrl"),PropKit.get("username"), PropKit.get("password")); dp.start(); } if (arp==null) { arp = new ActiveRecordPlugin(dp); // 打印sql語句 //arp.setShowSql(true); // 數據庫映射 arp.addMapping("user",User.class).setShowSql(Boolean.parseBoolean(PropKit.get( "showSql" ))); arp.start(); } //System.out.println("Begin..."); } @AfterAll static void tearDownAll() { //System.out.println("...End"); } }
讓測試類繼承自ManualOrmMap類,再次測試:
問題解決。
6. 既然orm層的配置沒有問題了,下面咱們來實現具體的業務邏輯
首先,在utils包下新建一個Result類,用來做爲先後端的數據交互格式,以下:
而後在package下新建子包service,而後新建類RegisterService。(Service層具體的處理業務流程)
public class RegisterService { //User dao private User userDao = new User().dao(); //對應RegisterController的addUser方法 public Result addUser(String username, String password, String email){ Result result = new Result(); if(username != null && !username.equals("") && password != null && !password.equals("") && email != null && !email.equals("")){ // List<User> checkUser = userDao.find("select * from user where username = ?",username); System.out.println(" >>>>> " + checkUser); if(checkUser != null && !checkUser.isEmpty()){ System.out.println("帳號已存在"); result.setStatus("1"); result.setMessage("該帳號已存在"); return result; } //執行保存 System.out.println("開始保存用戶信息"); User user = new User(); user.set("username",username); user.set("password",password); user.set("email",email); user.save(); result.setStatus("0"); result.setMessage("建立帳戶成功"); result.setData(user); return result; }else { result.setStatus("1"); result.setMessage("表單未完整填寫"); return result; } } }
OK,上述操做完成後,咱們來使用junit測試一下,一樣測試類須要繼承ManualOrmMap類,測試結果以下:
那麼。service層測試完畢後,咱們開始最後的整合。
7. 整合controller完成項目
爲了防止同窗們存在疑惑,下面貼一下,前端代碼(寫的比較亂,將就看):
<html> <head> <title>Jfinal Demo</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="http://cdn.static.runoob.com/libs/bootstrap/3.3.7/css/bootstrap.min.css"> <script src="http://cdn.static.runoob.com/libs/jquery/2.1.1/jquery.min.js"></script> <script src="http://cdn.static.runoob.com/libs/bootstrap/3.3.7/js/bootstrap.min.js"></script> <style> body{ background: linear-gradient(45deg,#BBDEFB,#F0F4C3); } </style> <script> $(document).ready(function(){ $("#sub").click(function(){ //測試 console.log($("#register").serialize()); $.ajax({url:"http://localhost:8088/addUser", data:$("#register").serialize(), success:function(result){ if(result.status == "0"){ $('#myModal').modal({ keyboard: true }); $(".modal-body").text(result.message); }else { $('#myModal').modal({ keyboard: true }); $(".modal-body").text(result.message); } }}); }); }); </script> </head> <body> <br> <h2 style="text-align: center;color: #B39DD8;">Welcome To Jfinal For OceanLi,Please Register</h2> <br> <div class="container" style="margin: 0 auto;width: 60%"> <div class="jumbotron" style="background-color: #FAFAFA;opacity: 0.6"> <div > <form id="register" role="form"> <div class="form-group"> <label for="register" style="text-align: center">名稱</label> <input type="text" class="form-control" name="username" placeholder="請輸入名稱"> </div> <div class="form-group"> <label for="register" style="text-align: center">密碼</label> <input type="password" class="form-control" name="password" placeholder="請輸入密碼"> </div> <div class="form-group"> <label for="register" style="text-align: center">郵箱</label> <input type="email" class="form-control" name="email" placeholder="請輸入郵箱"> </div> <div style="margin: 0 auto;text-align: center"> <button id="sub" type="button" class="btn btn-success btn-block" style="width: 60%;margin: 0 auto">提交註冊</button> </div> </form> </div> </div> </div> <!-- 模態框(Modal) --> <div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-hidden="true">× </button> <h4 class="modal-title" id="myModalLabel"> 註冊結果: </h4> </div> <div id="dialog_content" class="modal-body"> 註冊結果data.message </div> <div class="modal-footer"> <button type="button" class="btn btn-default" data-dismiss="modal">關閉 </button> </div> </div><!-- /.modal-content --> </div><!-- /.modal-dialog --> </div><!-- /.modal --> </body> </html>
8. 最後,咱們來啓動服務器,最終測試一下:
測試前,user表中的數據爲空
start:
咱們再來檢查一下數據庫:
完成。
測試下重複提交的狀況:
數據庫並無插入重複數據
9.最後的最後,貼給你們數據庫的sql腳本。
SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS = 0; -- ---------------------------- -- Table structure for `user` -- ---------------------------- DROP TABLE IF EXISTS `user`; CREATE TABLE `user` ( `id` int(11) NOT NULL AUTO_INCREMENT, `username` varchar(255) DEFAULT NULL, `password` varchar(255) DEFAULT NULL, `email` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=36 DEFAULT CHARSET=utf8; SET FOREIGN_KEY_CHECKS = 1;