SSM框架的前后端模板

一. 项目结构

本项目中包含一对多数据表的增删改查,模糊查询,分页。
前端部分内容需要layui

项目GitHub地址
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

二. 数据库

在这里插入图片描述

-- grade 班级表
DROP TABLE IF EXISTS `grade`;
CREATE TABLE `grade`  (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(100) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL,
  `address` varchar(100) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL,
  `create_date` datetime(0) NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 9 CHARACTER SET = utf8 COLLATE = utf8_bin ROW_FORMAT = Compact;
-- student 学生表
DROP TABLE IF EXISTS `student`;
CREATE TABLE `student`  (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL,
  `age` int(11) NULL DEFAULT NULL,
  `phone` varchar(11) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL,
  `home` varchar(100) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL,
  `g_id` int(11) NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE,
  INDEX `student_ibfk_1`(`g_id`) USING BTREE,
  CONSTRAINT `student_ibfk_1` FOREIGN KEY (`g_id`) REFERENCES `grade` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB AUTO_INCREMENT = 15 CHARACTER SET = utf8 COLLATE = utf8_bin ROW_FORMAT = Compact;

-- 数据
INSERT INTO `grade` VALUES (1, 'A1', '一教', '2020-01-01 07:00:00');
INSERT INTO `grade` VALUES (2, 'A2', '二教', '2020-01-02 08:00:00');
INSERT INTO `grade` VALUES (3, 'A3', '三机', '2020-01-10 12:00:00');
INSERT INTO `grade` VALUES (4, 'A4', '三教', '2020-05-01 07:30:00');
INSERT INTO `grade` VALUES (8, 'test1', 'test1', '2020-07-11 14:37:00');

INSERT INTO `student` VALUES (1, '张三', 18, '15122221112', '郑州', 1);
INSERT INTO `student` VALUES (2, '李四', 19, '15829392182', '洛阳', 1);
INSERT INTO `student` VALUES (3, '王五', 20, '15923239992', '南阳', 2);
INSERT INTO `student` VALUES (4, '韩六', 22, '13598929384', '北京', 2);
INSERT INTO `student` VALUES (5, '赵七', 20, '13922912231', '南京', 1);
INSERT INTO `student` VALUES (9, '阿狗', 18, '15122223333', '东北', 1);
INSERT INTO `student` VALUES (14, '2737110', 80, '15111111111', '123', 8);

三. 配置文件

配置文件见SSM框架配置文件

四. 基础模板

后端模板

  1. 需要fastjson插件,在pom文件中有坐标,建议使用1.2.72版本

  2. mybatis的mapper文件在resources文件夹下的mapper中,若需要更改为其他位置需要在spring-dao.xml文件中更改sqlSessionFactory下的mapperLocations指定的路径。

  3. 日期处理:后端接收前端时需要在实体类中的加入@DateTimeFormat(pattern = "yyyy-MM-dd'T'HH:mm")注解,后端向前端发送数据时需要加入@JSONField (format="yyyy-MM-dd'T'HH:mm")

    注:@DataTimeFormat注解需要在spring-web.xml中加入<mvc:annotation-driven />开启注解驱动,
    @JSONField注解需要fastjson支持,要在pom.xml中引入fastjson的坐标。

  4. 分页使用LayuiPageHelper进行分页辅助

1. BaseController

针对layui的Controller层模板

import com.aaa.service.BaseService;
import com.aaa.util.LayuiPageHelper;
import com.alibaba.fastjson.support.spring.FastJsonJsonView;
import org.springframework.web.servlet.ModelAndView;

/**
 * 对于layui的Controller层模板<br>
 * code:layui接收的唯一验证<br>
 * status:用于业务判断<br>
 * msg:向页面发送信息<br>
 * icon:页面图标<br>
 * data: 传输数据<br>
 * @author 淮南King
 */
public class BaseController {

    private BaseService service = null;

    public void init(BaseService service) {
        this.service = service;
    }

    /**
     * 添加模板
     * 传入继承BaseService的类
     *
     * @param entity 传入实体类
     * @param <T>
     * @return
     */
    public <T> ModelAndView add(T entity) {
        // 创建一个用于格式化json数据的对象,方便向前台发送json数据
        FastJsonJsonView view = new FastJsonJsonView();
        // 进行持久层操作
        int status = service.insert(entity);
        // 向view对象中添加数据
        view.addStaticAttribute("code", 0);
        if (status > 0) {
            view.addStaticAttribute("status", status);
            view.addStaticAttribute("icon", 1);
            view.addStaticAttribute("msg", "添加成功");
        } else {
            view.addStaticAttribute("status", status);
            view.addStaticAttribute("icon", 2);
            view.addStaticAttribute("msg", "添加失败");
        }
        // 返回json数据
        return new ModelAndView(view);
    }

    /**
     * 修改模板
     *
     * @param entity
     * @param <T>
     * @return
     */
    public <T> ModelAndView update(T entity) {
        // 创建一个用于格式化json数据的对象,方便向前台发送json数据
        FastJsonJsonView view = new FastJsonJsonView();
        // 进行持久层操作
        int status = service.update(entity);
        // 向view对象中添加数据
        view.addStaticAttribute("code", 0);
        if (status > 0) {
            view.addStaticAttribute("status", status);
            view.addStaticAttribute("icon", 1);
            view.addStaticAttribute("msg", "修改成功");
        } else {
            view.addStaticAttribute("status", status);
            view.addStaticAttribute("icon", 2);
            view.addStaticAttribute("msg", "修改失败");
        }

        // 返回json数据
        return new ModelAndView(view);
    }

    /**
     * 删除模板
     *
     * @param entity
     * @param <T>
     * @return
     */
    public <T> ModelAndView delete(T entity) {
        // 创建一个用于格式化json数据的对象,方便向前台发送json数据
        FastJsonJsonView view = new FastJsonJsonView();
        // 进行持久层操作
        int status = 0;
        // 规避删除时一对多时删除父表内容时删除失败
        try {
            status = service.delete(entity);
        } catch (Exception e) {
            status = 0;
        }
        // 向view对象中添加数据
        view.addStaticAttribute("code", 0);
        if (status > 0) {
            view.addStaticAttribute("status", status);
            view.addStaticAttribute("icon", 1);
            view.addStaticAttribute("msg", "删除成功!");
        } else {
            view.addStaticAttribute("status", status);
            view.addStaticAttribute("icon", 2);
            view.addStaticAttribute("msg", "删除失败!");
        }
        // 返回json数据
        return new ModelAndView(view);
    }

    /**
     * 查询一条数据
     *
     * @param entity
     * @param <T>
     * @return
     */
    public <T> ModelAndView findOne(T entity) {
        // 去查询
        Object one = service.findOne(entity);
        // 创建一个用于格式化json数据的对象,方便向前台发送json数据
        FastJsonJsonView view = new FastJsonJsonView();
        // 向view对象中添加数据
        view.addStaticAttribute("code", 0);
        view.addStaticAttribute("status", 1);
        view.addStaticAttribute("data", one);
        // 返回json数据
        return new ModelAndView(view);
    }

    /**
     * 分页查询方法
     *
     * @param page
     * @param entity
     * @param objects
     * @param <T>
     * @return
     */
    public <T> ModelAndView findPage(LayuiPageHelper page, T entity, Object... objects) {
        // 创建一个用于格式化json数据的对象,方便向前台发送json数据
        FastJsonJsonView view = new FastJsonJsonView();
        // 创建pageHelper对象,用于分页
        LayuiPageHelper pages = new LayuiPageHelper();
        // 从数据库查询总数
        pages.setCount(service.dataCount(entity, objects));
        // 设置当前页
        pages.setPageNow(page.getPageNow() == 0 ? 1 : Integer.valueOf(page.getPageNow()));
        // 设置页大小
        pages.setPageSize(page.getPageSize() == 0 ? 5 : Integer.valueOf(page.getPageSize()));
        // 向view对象中添加数据
        view.addStaticAttribute("code", 0);
        view.addStaticAttribute("message", "查询成功");
        view.addStaticAttribute("count", pages.getCount());
        // -----------------------------------从数据查询数据信息
        view.addStaticAttribute("data", service.findPage(entity, pages, objects));
        // 返回json数据
        return new ModelAndView(view);
    }
}

2. BaseMapper

用于mybatis的mapper接口,可直接进行继承

package com.aaa.mapper;

import com.aaa.util.LayuiPageHelper;
import org.apache.ibatis.annotations.Param;

import java.util.List;

/**
 * Mapper模板
 * @author 淮南King
 * @date 2020-07-04
 */
public interface BaseMapper<T> {
    int insert(@Param("beans") T t);

    int update(@Param("beans") T t);

    int delete(@Param("beans") T t);

    List<T> findPage(@Param("beans") T t, @Param("page") LayuiPageHelper page, @Param("obj") Object... objects);

    int dataCount(@Param("beans") T t, @Param("obj") Object... objects);

    T findOne(@Param("beans") T t);

}

3. BaseService

Service层模板

package com.aaa.service;

import com.aaa.mapper.BaseMapper;
import com.aaa.util.LayuiPageHelper;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * Service层模板
 * @author 淮南King
 * @date 2020-07-04
 */
@Service
public abstract class BaseService<T> {
    /**
     * 用于获取Mapper
     * @return
     */
    public abstract BaseMapper<T> getDao();

    public int insert(T entity) {
        return getDao().insert(entity);
    }

    public int update(T entity) {
        return getDao().update(entity);
    }

    public int delete(T entity) {
        return getDao().delete(entity);
    }

    public List<T> findPage(T t, LayuiPageHelper page, Object... objects) {
        return getDao().findPage(t, page, objects);
    }

    public T findOne(T entity) {
        return getDao().findOne(entity);
    }

    public int dataCount(T entity, Object... objects) {
        return getDao().dataCount(entity, objects);
    }
}

4. LayuiPageHelper

适用于layui中的分页插件

package com.aaa.util;

/**
 * 适用于layui中的分页插件
 * @author 淮南King
 * @date 2020-07-04
 */
public class LayuiPageHelper {
    private int begin = 0;
    private int pageSize = 10;
    private int count = 0;
    private int pageNow = 1;
    private int pageTotal = 0;
    /** 用于接受layui发送的当前页 */
    private int page = 1;
    /** 用于接受layui发送的页大小 */
    private int limit = 5;

    public LayuiPageHelper() {
    }

    public LayuiPageHelper(int page, int limit) {
        this.page = page;
        this.limit = limit;
    }

    public int getPage() {
        return pageNow;
    }

    public void setPage(int page) {
        this.page = page;
        this.pageNow = page;
    }

    public int getLimit() {
        return pageSize;
    }

    public void setLimit(int limit) {
        this.pageSize = limit;
        this.limit = limit;
    }

    public int getBegin() {
        this.begin = (this.pageNow - 1) * this.pageSize;
        return begin;
    }

    public void setBegin(int begin) {
        this.begin = begin;
    }

    public int getPageSize() {
        return pageSize;
    }

    public void setPageSize(int pageSize) {
        this.pageSize = pageSize;
    }

    public int getCount() {
        return count;
    }

    public void setCount(int count) {
        this.count = count;
    }

    public int getPageNow() {
        return pageNow;
    }

    public void setPageNow(int pageNow) {
        this.pageNow = pageNow;
    }

    public int getPageTotal() {
        this.pageTotal = this.count % this.pageSize == 0 ? this.count / this.pageSize : this.count / this.pageSize + 1;
        return pageTotal;
    }

    public void setPageTotal(int pageTotal) {
        this.pageTotal = pageTotal;
    }
}

前端模板

  1. 使用layui进行页面美化,layui官网传送门
  2. 前端使用Ajax向后端发送请求
  3. list为显示表格页面,form为添加和修改的页面,通过url带参数让form页面进行动态改变

1. list.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%request.setAttribute("pn", pageContext.getServletContext().getContextPath());%>
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>展示信息</title>
    <link rel="stylesheet" href="${pn}/static/layui/css/layui.css">
</head>
<body>
<!-- layui-card 包括整个页面 -->
<div class="layui-card">
    <!-- 表头搜索部分 -->
    <div class="layui-form">
        <div class="layui-form-item">
            <!-- 文本输入框,用于模糊查询 -->
            <div class="layui-inline">
                <input type="text" id="entityName" placeholder="请输入内容" autocomplete="off"
                       class="layui-input">
            </div>
            <!-- 搜索按钮 -->
            <div class="layui-inline">
                <button class="layui-btn layui-btn-radius layui-btn-normal" id="entity_search">
                    <i class="layui-icon layui-icon-search"></i>
                </button>
            </div>
            <!-- 新增按钮 -->
            <div class="layui-inline">
                <button class="layui-btn layui-btn-radius layui-btn-normal"
                        onclick="windowOpen('form.jsp?url=/grade/add')">添加
                </button>
            </div>
            <!-- 查看学生信息列表 -->
            <div class="layui-inline">
                <a class="layui-btn layui-btn-radius layui-btn-normal" href="../StudentAndGrade/list.jsp">查看学生信息</a>
            </div>
        </div>
    </div>
    <!-- table部分 -->
    <div class="layui-card-body">
        <table id="datatable" lay-filter="datatable"></table>
    </div>
</div>

<script src="${pn}/static/layui/layui.js"></script>
<!-- table表格尾部的按钮元素 -->
<script type="text/html" id="table_bar">
    <div class="layui-btn-container">
        <a class="layui-btn layui-btn-xs" lay-event="edit">编辑</a>
        <a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del">删除</a>
    </div>
</script>
<script type="text/javascript">
    // layui 部分
    layui.use(['table', 'util'], function () {
        var $ = layui.$,
            table = layui.table,
            util = layui.util;
        //表格配置
        table.render({
            elem: '#datatable'
            , height: 400
            , url: '/grade/findAll' //数据接口
            , page: true //开启分页
            , limits: [3, 5, 10, 20]
            , cols: [[ //表头
                {field: 'gId', title: 'ID', width: 80, fixed: 'left'}
                , {field: 'gName', title: '班级名称'}
                , {field: 'address', title: '教室'}
                , {
                    field: 'createDate', title: '班级创建日期',
                    templet: function (d) {
                        return util.toDateString(d.createDate, 'yyyy-MM-dd HH:mm:ss')
                    }
                }
                , {fixed: 'right', title: '操作', align: 'center', toolbar: '#table_bar'}
            ]]
            , where: {'gName': $("#entityName").val()}
        });

        //监听搜索按钮
        $("#entity_search").on('click', function (data) {
            //刷新表格中的内容
            table.reload('datatable', {
                method: 'post'
                , where: {'gName': $("#entityName").val()}
                , page: {curr: 1}
            });
        });

        //监听行工具事件
        table.on('tool(datatable)', function (obj) { //注:tool 是工具条事件名,zq_table 是 table 原始容器的属性 lay-filter="对应的值"
            const data = obj.data //获得当前行数据
                , layEvent = obj.event; //获得 lay-event 对应的值(也可以是表头的 event 参数对应的值)
            const tr = obj.tr; //获得当前行 tr 的DOM对象
            switch (layEvent) {
                case 'del':
                    layer.confirm('您确定删除id:' + data.gId + '的数据吗?', function (index) {
                        $.post("/grade/delete", {gId: data.gId}, function (ret) {
                            layer.msg(ret.msg);
                            if (ret.status == 1) {//删除成功,刷新当前页表格
                                $("#entity_search").click();
                                layer.close(index);
                            }
                        });
                    });
                    break;
                case 'edit':
                    windowOpen("form.jsp?url=/grade/update&gId=" + data.gId);
                    break;
            }
        });
    });


    var windowsOpen = {};//定义全局变量

    //开启一个窗口
    function windowOpen(url) {
        const l = (screen.availWidth - 375) / 2;
        const t = (screen.availHeight - 667) / 2;
        windowsOpen = window.open(url, '', 'height=500, width=600, top=' + t + ', left=' + l + ', toolbar=no, ' +
            'menubar=no, scrollbars=no, resizable=no,location=no, status=no');
    }
</script>

</body>
</html>

2. form.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%request.setAttribute("pn", pageContext.getServletContext().getContextPath());%>
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>表单数据</title>
    <link rel="stylesheet" href="${pn}/static/layui/css/layui.css">
</head>
<body>

<div class="layui-card">
    <div class="layui-form">
        <input type="hidden" id="gId" value="0"/>
        <div class="layui-form-item">
            <label class="layui-form-label">班级名称</label>
            <div class="layui-input-inline">
                <input type="text" id="gName" lay-verify="required" class="layui-input">
            </div>
        </div>
        <div class="layui-form-item">
            <div class="layui-inline">
                <label class="layui-form-label">教室</label>
                <div class="layui-input-block">
                    <input type="text" id="address" lay-verify="required" class="layui-input">
                </div>
            </div>
        </div>
        <div class="layui-form-item">
            <div class="layui-inline">
                <label class="layui-form-label">创建日期</label>
                <div class="layui-input-block">
                    <input type="datetime-local" id="createDate" lay-verify="required" class="layui-input">
                </div>
            </div>
        </div>
        <div class="layui-form-item">
            <input class="layui-btn layui-btn-radius layui-btn-normal" type="button" id="submit"
                   value="添加">
            <input class="layui-btn layui-btn-radius layui-btn-primary" type="button" id="reset"
                   onclick="closeSelf()" value="取消">
        </div>
    </div>
</div>
<script src="${pn}/static/layui/layui.js" charset="UTF-8"></script>
<script src="${pn}/static/jquery-1.8.3.min.js" charset="UTF-8"></script>
<script>
    //获取URL中的参数id
    function getQueryVariable(variable) {
        const query = window.location.search.substring(1);
        const vars = query.split("&");
        for (var i = 0; i < vars.length; i++) {
            var pair = vars[i].split("=");
            if (pair[0] == variable) {
                return pair[1];
            }
        }
        return (false);
    }
    //获取当前URL中的提交链接
    const elemUrl = getQueryVariable('url')
    //判断是否需要修改链接,若是修改链接则向后台请求当前数据详情
    if(elemUrl.indexOf("update") != -1){
        $.ajax({
            url: "/grade/findOne",
            type: 'post',
            dataType: 'json',
            async: false,//设置阻断
            data: {
                "gId": getQueryVariable('gId'),
            },
            success: function (data) {
                $("#gId").val(data.data.gId);
                $("#gName").val(data.data.gName)
                $("#address").val(data.data.address)
                $("#createDate").val(data.data.createDate)
            }
        });
    }

    layui.use(['layer','form'], function () {
        var $ = layui.$,
            form = layui.form,
            layer = layui.layer;

        //监听提交
        $("#submit").on('click', function (data) {
            $.ajax({
                url: elemUrl,
                type: 'post',
                dataType: 'json',
                async: false,//设置阻断
                data: {
                    "gId":$("#gId").val(),
                    "gName": $("#gName").val(),
                    "address": $("#address").val(),
                    "createDate": $("#createDate").val()
                },
                success: function (data) {
                    layer.msg(data.msg);
                    //父窗口刷新
                    window.opener.location.reload();
                    //关闭当前窗口
                    window.close()
                }
            });
        });
    })
</script>
</body>
</html>
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值