JFinal框架简单使用及增删查改分页功能实现

摘要

JFinal 是基于 Java 语言的极速 WEB + ORM 框架,其核心设计目标是开发迅速、代码量少、学习简单、功能强大、轻量级、易扩展、Restful。在拥有Java语言所有优势的同时再拥有ruby、python、php等动态语言的开发效率!为您节约更多时间,去陪恋人、家人和朋友 :)
JFinal有如下主要特点:
MVC架构,设计精巧,使用简单
遵循COC原则,零配置,无xml
独创Db + Record模式,灵活便利
ActiveRecord支持,使数据库开发极致快速
自动加载修改后的java文件,开发过程中无需重启web server
AOP支持,拦截器配置灵活,功能强大
Plugin体系结构,扩展性强
多视图支持,支持FreeMarker、JSP、Velocity
强大的Validator后端校验功能
功能齐全,拥有struts2的绝大部分功能
体积小仅339K,且无第三方依赖

JFinal开发环境搭建

该项目使用的IntelliJ IDEA进行开发,具体怎么搭建JFinal项目,请移步IntelliJ IDEA 14.1上JFinal开发环境搭建手册这篇博客介绍的很详细,这里就不在赘述了。该项目结构如下图:
这里写图片描述

链接数据库

1.导入Jar包

这里写图片描述

2.创建mysql数据库jfinal

新建表blog
id—-自动编号
title—-varchar
content—-text
pubtime—-datetim
这里写图片描述

3.创建数据库配置文件

右键src—new—file,输入config.properties
打开该文件,输入

jdbcUrl = jdbc:mysql://127.0.0.1/jfinal?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull 
user = root 
password = root 
devMode =true

修改IP地址,数据库名,账号密码等 devMode =true表示开发模式,在开发完毕正式运行环境下可以设置为false。

配置CommonConfig.java

在CommonConfig.java中配置数据源、常量等信息

1.在configConstant方法中配置常量

  @Override
    public void configConstant(Constants me) {
        PropKit.use("config.properties"); //加载配置文件
//        me.setViewType(ViewType.JSP); // Jsp 界面
        me.setDevMode(PropKit.getBoolean("devMode", false));
    }

2.在configPlugin方法中配置数据源连接

    public static DruidPlugin createDruidPlugin() {
            return new DruidPlugin(PropKit.get("jdbcUrl").trim(), PropKit.get("user").trim(), PropKit.get("password").trim());
    }


    @Override
    public void configPlugin(Plugins me) {
        // 配置C3p0数据库连接池插件
        DruidPlugin druidPlugin = createDruidPlugin();
        me.add(druidPlugin);
        // 配置ActiveRecord插件
        ActiveRecordPlugin arp = new ActiveRecordPlugin(druidPlugin);
        // 所有映射在 MappingKit 中自动化搞定
        MappingKit.mapping(arp);
        me.add(arp);
    }

在model包下新建MappingKit类,所有映射在 MappingKit 中自动化搞定。

数据库映射:数据库中的表跟java类的对应关系。

public class MappingKit {

    public static void mapping(ActiveRecordPlugin arp) {
        arp.addMapping("blog", "id", Blog.class);
    }

}

3.在configRoute方法中配置路由

路由:指定浏览器里输入的/blog由哪个控制器来处理。

    @Override
    public void configRoute(Routes me) {
        me.setBaseViewPath("WEB-INF/view"); // 设置默认试图路径
        me.add("/", IndexController.class);
        me.add("/hello", HelloController.class);
        me.add("/blog", BlogController.class, "/blog"); // 由Jsp实现 
        me.add("/blog-html", BlogHtmlController.class, "/blog"); // 由Html实现
    }

访问/blog由BlogController控制器处理,使用的试图路径为setBaseViewPath配置的路径下的blog目录。如果路径名称不是blog,可以设置第三个参数 me.add(“/blog”, BlogController.class, “blog”); 这样就是指定到WEB-INF/view/blog目录

创建Model实体类

在model包新建base包,在base包下创建BaseBlog.class

@SuppressWarnings({"serial", "unchecked"})
public abstract class BaseBlog<M extends BaseBlog<M>> extends Model<M> implements IBean {

    public M setId(Integer id) {
        set("id", id);
        return (M) this;
    }

    public Integer getId() {
        return get("id");
    }

    public M setTitle(String title) {
        set("title", title);
        return (M) this;
    }

    public String getTitle() {
        return get("title");
    }

    public M setContent(String content) {
        set("content", content);
        return (M) this;
    }

    public String getContent() {
        return get("content");
    }

    public M setPubTime(String pubtime) {
        set("pubtime", pubtime);
        return (M) this;
    }

    public String getPubTime() {
        return get("pubtime");
    }

}

在model包下新建Blog.class继承BaseBlog。

public class Blog extends BaseBlog<Blog> {

    public static final Blog me = new Blog().dao();

    /**
     * 所有 sql 与业务逻辑写在 Service 中,在此放在 Model 中仅为示例,
     * 不要写在 Controller 中,养成好习惯,有利于大型项目的开发与维护
     */
    public Page<Blog> paginate(int pageNumber, int pageSize) {
        return paginate(pageNumber, pageSize, "select *", "from blog order by id asc");
    }
}

对数据库的增删查改以及分页

一、Jsp + jQuery

数据库增删查改

创建Controller

创建BlogController.class继承com.jfinal.core.Controller;包下Controller。

1.从数据库中查询数据,并显示。

public class BlogController extends Controller {

    @Override
    public void index() {
        List<Blog> mBlogLst = Blog.me.find("select * from blog"); // 查询数据给ArrayList
        for (Blog mItem : mBlogLst) {
            if (mItem.getDate("pubtime") != null)
                 mItem.setPubTime(DateUtils.DateToString(mItem.getDate("pubtime"), "yyyy/MM/dd HH:mm:ss"));
        }
        String dataStr = JsonUtils.serialize(mBlogLst);
        setAttr("data", dataStr);
        render("index.jsp"); // 渲染视图文件
    }
}

在WEB-INF/view目录下,创建blog文件夹,新建index.jsp。

body部分代码:

<div class="nav">
    <a href="/blog/form" class="add">新增</a>
</div>
<div>

</div>
<div class="table_box">
    <table class="list">
        <tbody id="blog_lst">

        </tbody>
    </table>
</div>

js部分代码:

<script type="text/javascript">

$(document).ready(function () {
        var mblogLst = ${data};
        var str = "";
        $("#blog_lst").empty();
        for (var i = 0; i < mblogLst.length; i++) {
            str += "<tr>";
            str += "<td>" + mblogLst[i].id + "</td>";
            str += "<td>" + mblogLst[i].title + "</td>";
            str += "<td>" + mblogLst[i].content + "</td>";
            str += "<td>" + mblogLst[i].pubTime + "</td>";
            str += "<td>";
            str += "<a href='/blog/delete/" + mblogLst[i].id + "'>" + "删除" + "</a>";
            str += "<a href='/blog/form/" + mblogLst[i].id + "'>" + "修改" + "</a>";
            str += "</td>";
            str += "</tr>";
        }
        $("#blog_lst").html(str);
}
</script>

2.向数据库中添加数据和修改数据。

在界面点击新增按钮,执行BlogController 中form方法。在BlogController 中新增form方法(由于后面form界面会被改成新增和修改的公共界面,所以这里的form方法是修改后的公共方法):

    public void form() {
        Integer id = getParaToInt(0); //获取id参数
        if (id != null && id > 0) { // 如果id不为空且大于0,执行编辑操作
            setAttr("blog", Blog.me.findById(id));// 从数据库中找到该条记录放到request对象中
        }
        render("form.jsp");// 渲染页面
    }

在WEB-INF/view目录下,创建blog文件夹,新建form.jsp。

body部分代码:

<form method="post" action="/blog/save">
    <input type="hidden" name="blog.id" value="${blog.id}"/>

    <div class="form_title">
        <div>Title:</div>
        <input type="text" name="blog.title" value="${blog.title}"/>
    </div>

    <div class="form_content">
        <div>Content:</div>
        <textarea name="blog.content">${blog.content}</textarea>
    </div>

    <input class="form_btn" type="submit" value=" 提交 "/>
</form>

点击提交后,会执行BlogController 中的save方法。在BlogController 添加save方法:

   public void save() {
        Blog blog = getModel(Blog.class, "blog");// 将表单中的数据转成blog对象
        if (blog.get("id") == null) { // 新增
            blog.set("pubtime", new Date()); // 添加发布时间
            blog.save(); // 保存数据
        } else if (blog.getInt("id") > 0) { // 修改
            blog.update();
        }
        index();// 访问index方法跳转到显示列表页
    }

3.删除数据库中的数据:

在界面点击删除按钮后,会执行BlogController 中的delete方法。在BlogController 添加delete方法:

    /**
     * 删除/blog/delete?id=4
     */
    public void delete() {
        Integer id = getParaToInt(0); //获取id参数
        if (id != null && id > 0) {
            boolean flag = Blog.me.deleteById(id); //执行删除操作
            if (!flag) {
                renderText("删除失败");
                return; //结束,不再往下执行。
            }
        } else {
            renderText("删除失败");
            return; //结束,不再往下执行。
        }
        index(); //如果删除成功的话,跳转到显示列表页
    }
分页

分页主要是使用jQuery完成数据分页功能,利用ajax发送请求,并就收后台返回的数据。所以index.jsp界面的js代码修改为:

<script type="text/javascript">
    function showBlogLst(blogLst) {
        var mblogLst = blogLst;
        var str = "";
        $("#blog_lst").empty();
        for (var i = 0; i < mblogLst.length; i++) {
            str += "<tr>";
            str += "<td>" + mblogLst[i].id + "</td>";
            str += "<td>" + mblogLst[i].title + "</td>";
            str += "<td>" + mblogLst[i].content + "</td>";
            str += "<td>" + mblogLst[i].pubTime + "</td>";
            str += "<td>";
            str += "<a href='/blog/delete/" + mblogLst[i].id + "'>" + "删除" + "</a>";
            str += "<a href='/blog/form/" + mblogLst[i].id + "'>" + "修改" + "</a>";
            str += "</td>";
            str += "</tr>";
        }
        $("#blog_lst").html(str);
    }

    function PageFoot2(blogPage) {
        var n = "";
        var backword = "上一页";
        var forword = "下一页";
        var x = blogPage.pageNumber; //当前页
        var back; //前一页
        var next; //后一页
        if (x == 1) { //对上一页的判断
            back = 1;
        } else {
            back = x - 1;
        }
        if (x < blogPage.totalPage) { //对下一页判断
            next = x + 1;
        } else {
            next = blogPage.totalPage;
        }
        n += "<li onclick=\"showPage2(" + back + ")\"><a>" + backword + "</a></li>  ";
        for (var a = 1; a <= blogPage.totalPage; a++) {
            if (a == blogPage.pageNumber) {
                n += "<li class=\"active\" onclick=\"showPage2(" + a + ")\"><a>" + a + "</a></li>  ";
            } else {
                n += "<li onclick=\"showPage2(" + a + ")\"><a>" + a + "</a></li>  ";
            }
        }
        n += "<li onclick=\"showPage2(" + next + ")\"><a>" + forword + "</a></li>  ";
        $("#pagefoot").html(n); //把循环好的页码给替换掉
    };

    function showPage2(curr) {
        $.ajax({
            type: "get",
            url: "/blog/paginate",
            data: {"pageNumber": curr},
            cache: false,
            async: false,
            dataType: "json",
            success: function (data) {
                showBlogLst(data.blogLst);
                PageFoot2(data.blogPage);
                return true;
            },
            error: function (XMLHttpRequest, textStatus, errorThrown) {
                alert("请求失败!");
            }
        });
    }
    showPage2(1); //刚进入页面为第一页,列出第一页数据和页脚
</script>

在BlogController 添加paginate方法:

    /**
     * 分页
     */
    public void paginate() {
        Page<Blog> mBlogPage = Blog.me.paginate(getParaToInt("pageNumber", 1), 5);
        List<Blog> mBlogLst = mBlogPage.getList();
        for (Blog mItem : mBlogLst) {
            if (mItem.getDate("pubtime") != null)
                mItem.setPubTime(DateUtils.DateToString(mItem.getDate("pubtime"), "yyyy/MM/dd HH:mm:ss"));
        }
        HashMap<String, Object> map = new HashMap<>();
        map.put("blogLst", mBlogLst);
        map.put("blogPage", mBlogPage);
        renderJson(map);
    }

二、JFinal template engine

利用JFinal template主要是界面上的不同,Controller代码都差不多一样,就不多说了。单单说说Html的显示和分页。

在CommonConfig中的configEngine方法中添加需要添加的template:

    @Override
    public void configEngine(Engine me) {
        me.addSharedFunction("WEB-INF/view/common/_layout.html");
        me.addSharedFunction("WEB-INF/view/common/_paginate.html");
    }

这两个template,在JFinal官网的demo实例就可找到。

form.html界面和form.jsp body部分的代码一样,这里只看看index.html部分:

<div class="nav">
    <a href="/blog-html/form" class="add">新增</a>
</div>
<div>

</div>
<div class="table_box">
    <table class="list">
        <tbody id="blog_lst">
        <tr>
            <th>id</th>
            <th>标题</th>
            <th>内容</th>
            <th>发布时间</th>
            <th>操作</th>
        </tr>
        #for(x : blogPage.getList())
        <tr>
            <td>#(x.id)</td>
            <td>#(x.title)</td>
            <td>#(x.content)</td>
            <td>#(x.pubtime)</td>
            <td>
                &nbsp;&nbsp;<a href="/blog-html/delete/#(x.id)">删除</a>
                &nbsp;&nbsp;<a href="/blog-html/form/#(x.id)">修改</a>
            </td>
        </tr>
        #end
        </tbody>
    </table>
</div>

BlogHtmlController中的index方法只需:

    @Override
    public void index() {
        setAttr("blogPage", Blog.me.paginate(getParaToInt(0, 1), 10));
        render("index.html"); // 渲染视图文件
    }

就可完成对数据的展示。

分页

分页更加简单,只需在需要显示分页的地方加上:

#@paginate(blogPage.pageNumber, blogPage.totalPage, "/blog-html/")

最后index.html界面body部分代码:

<div class="nav">
    <a href="/blog-html/form" class="add">新增</a>
</div>
<div>

</div>
<div class="table_box">
    <table class="list">
        <tbody id="blog_lst">
        <tr>
            <th>id</th>
            <th>标题</th>
            <th>内容</th>
            <th>发布时间</th>
            <th>操作</th>
        </tr>
        #for(x : blogPage.getList())
        <tr>
            <td>#(x.id)</td>
            <td>#(x.title)</td>
            <td>#(x.content)</td>
            <td>#(x.pubtime)</td>
            <td>
                &nbsp;&nbsp;<a href="/blog-html/delete/#(x.id)">删除</a>
                &nbsp;&nbsp;<a href="/blog-html/form/#(x.id)">修改</a>
            </td>
        </tr>
        #end
        </tbody>
    </table>
</div>
#@paginate(blogPage.pageNumber, blogPage.totalPage, "/blog-html/")

结束

写这篇博客呢,主要是记一个笔记,有一些地方可能些的并不是很清楚,代码直接拷过去也有可能有问题,毕竟这是我从写好的代码里抠出来的,哈哈哈哈哈。有不足的地方希望指正一下。谢谢。
完整的代码:请点传送门

  • 2
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
使用 JFinal 实现增删改查操作非常简单。首先,你需要在你的项目中添加 JFinal 的依赖。可以在 pom.xml 文件中添加以下依赖: ```xml <dependency> <groupId>com.jfinal</groupId> <artifactId>jfinal</artifactId> <version>3.6</version> </dependency> ``` 然后,创建一个继承自 `com.jfinal.core.Controller` 类的控制器,用于处理请求。在控制器中,你可以定义各种方法来处理增删改查操作。 以实现一个简单的用户管理系统为例,我们可以创建一个 `UserController` 类来处理用户相关的请求。在该类中,我们可以定义以下方法: 1. 查询所有用户: ```java public void index() { List<User> userList = User.dao.findAll(); setAttr("userList", userList); render("user_list.html"); } ``` 2. 添加用户: ```java public void add() { User user = getModel(User.class, ""); user.save(); redirect("/user"); } ``` 3. 编辑用户: ```java public void edit() { int userId = getParaToInt("id"); User user = User.dao.findById(userId); setAttr("user", user); render("edit_user.html"); } public void update() { User user = getModel(User.class, ""); user.update(); redirect("/user"); } ``` 4. 删除用户: ```java public void delete() { int userId = getParaToInt("id"); User.dao.deleteById(userId); redirect("/user"); } ``` 在以上代码中,`User` 是一个继承自 `com.jfinal.plugin.activerecord.Model` 的模型类,用于操作数据库中的用户表。 这只是一个简单的示例,你可以根据自己的需求进行适当的修改和扩展。同时,你还需要在配置文件中配置数据库连接等相关信息。详细的配置和使用方法可以参考 JFinal 官方文档:https://jfinal.com/doc/。 希望这个示例能对你有所帮助!如果你有任何疑问,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值