Jfinal——实践出真知

什么是Jfinal?

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

  简单来说,Jfinal是一套基于微内核的快速开发框架。给开发者提供更高效、易用的工具框架。

Jfinal的特点:

  • MVC架构,设计精巧,使用简单
  • 遵循COC原则,零配置,无xml
  • 独创Db + Record模式,灵活便利
  • ActiveRecord支持,使数据库开发极致快速
  • 极简、高性能Template Engine,十分钟内掌握基本用法
  • 自动加载修改后的java文件,开发过程中无需重启web server
  • AOP支持,拦截器配置灵活,功能强大
  • Plugin体系结构,扩展性强
  • 多视图支持,支持FreeMarker、JSP、Velocity
  • 强大的Validator后端校验功能
  • 功能齐全,拥有struts2的绝大部分功能
  • 体积小仅580K

  Ps:开源Jfinal项目详情,点击这里进入

为什么要写这篇博客:

  写这篇博客的目的呢,其实很简单。

  其一:官方的文档不具连贯性,都是某某API的用法和介绍,小白的话读了文档可能还是两脸懵逼😂(其实笔者就是这个小白);俗话说纸上得来终觉浅嘛,所以自己有思路以后希望写一篇以 用户注册功能 为需求的Jfinal的搭建、入门、和简单的开发流程的一个教程;希望可以帮到像我一样的孩纸。

  其二:于自己来说是一个总结,可以用作为一个初步掌握Jfinal的视角去重新的审视自己的学习过程。

  其三:装个X嘛🤪

开始自己的Demo:

  好了,前面废话了那么多。对Jfinal有了初步的了解后,下面咱们开干吧:(开发环境为:IDEA For Mac,项目管理工具使用Maven)

  1. 首先,使用maven创建一个web项目,如图:

 

  

 

 

 在pom.xml中添加jar包依赖,其中jfinal相关的两个是必须的,junit作为单元测试,最后两个用来连接数据库

  <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。

  •   将WEB-INF下的除web.xml以外的文件删除
  •   在src/main下创建一个java文件夹
  •   将java设为code source
  •   可选(有需要的可以更改编译的输出目录,idea默认在target/classes下)
  •   将webapp改名为WebRoot
  •   在src/main/java下建立自己的package

更改完成后,如图:

  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层配置

  •   在package下创建子包model
  •   在model下创建数据库映射实体类
  •   在resources文件夹下新建db.properties,用来保存相关数据库连接参数
  •     在AppConfig的configConstant()方法内 加载配置文件
  •   在AppConfig的configPlugin()方法内配置数据库插件(Druid、mysql-connect ...)

  具体操作因业务/情况而定,我的配置如下:

  这是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;

 

posted @ 2018-01-18 19:27  昕无旁骛  阅读(584)  评论(0编辑  收藏  举报