文章目录
前面写了个简单的登陆功能,这里就简单的实现一下crud。
dao层
实体
package com.example.student.entity;
import java.util.Date;
/**
* 学生信息表
*
* @author xiaotao
*/
public class StudentDO {
/**
* 主键
*/
private String id;
/**
* 姓名
*/
private String name;
/**
* 年龄
*/
private Integer age;
/**
* 性别
*/
private String sex;
/**
* 创建日期
*/
private Date createTime;
/**
* 更新时间
*/
private Date updateTime;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public Date getUpdateTime() {
return updateTime;
}
public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime;
}
@Override
public String toString() {
return "StudentDO{" +
"id='" + id + '\'' +
", name='" + name + '\'' +
", age=" + age +
", sex='" + sex + '\'' +
", createTime=" + createTime +
", updateTime=" + updateTime +
'}';
}
}
访问对象
这里count接口是干什么的呢,其实是用来前端分页的。
我们前端使用表格来显示学生信息,但是我们几乎不会用表格的一页显示所有数据,所有需要分页,这里大致分服务器分页和客户端分页。
- 客户端分页:一次性加载所有数据,切换数据不会再请求服务器。
- 服务器分页:显示多少数据,请求多少数据。
我们这里采用服务器分页,count就是用来统计数据的总量。
为什么要有这个接口呢,当然是我们后面service会用到了。。。所以后面再讲。
count和getStudent的参数是用来传递搜索信息的,这里我们搜索就放在数据库了,所以你在其他层是看不到搜索相关代码的。
package com.example.student.dao;
import com.example.student.entity.StudentDO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Map;
/**
* 学生DAO接口
*
* @author xiaotao
*/
@Mapper
public interface StudentDAO {
/**
* 获得学生信息数据的数量
*
* @param params 过滤参数
* @return 学生的数量
*/
int count(Map<String, Object> params);
/**
* 获取学生信息
*
* @param params 过滤参数
* @return 学生信息主表链表
*/
List<StudentDO> getStudent(Map<String, Object> params);
/**
* 插入一条记录
*
* @param studentDO 实体
*/
void insert(StudentDO studentDO);
/**
* 删除
*
* @param id 主键
*/
void delete(@Param("id") String id);
/**
* 修改客户信息
*
* @param studentDO 实体信息
*/
void update(StudentDO studentDO);
}
xml文件
这里搜索就只搜索了name一个字段。
getStudent里面ORDER BY ${sort} ${order}
用来按照字段排序,LIMIT #{offset}, #{limit}
用来分页的,选取我们需要的数据。
insert里面selectKey可以自动生成id。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.student.dao.StudentDAO">
<resultMap id="StudentDO" type="com.example.student.entity.StudentDO">
<id column="id" property="id" jdbcType="VARCHAR"/>
<result column="name" property="name"/>
<result column="age" property="age"/>
<result column="sex" property="sex"/>
<result column="create_time" property="createTime"/>
<result column="update_time" property="updateTime"/>
</resultMap>
<select id="count" resultType="java.lang.Integer">
SELECT count(*)
FROM `t_student`
<where>
<if test="name != null"> AND `name` LIKE CONCAT('%', #{name ,jdbcType=VARCHAR}, '%') </if>
</where>
</select>
<select id="getStudent" resultMap="StudentDO">
SELECT *
FROM `t_student`
<where>
<if test="name != null"> AND `name` LIKE CONCAT('%', #{name ,jdbcType=VARCHAR}, '%') </if>
</where>
<choose>
<when test="sort != null and sort.trim() != ''">
ORDER BY ${sort} ${order}
</when>
</choose>
<if test="offset != null and limit != null">
LIMIT #{offset}, #{limit}
</if>
</select>
<insert id="insert" parameterType="com.example.student.entity.StudentDO">
<selectKey keyProperty="id" resultType="String" order="BEFORE">
SELECT replace(uuid(),'-','') FROM dual;
</selectKey>
INSERT INTO `t_student` (`id`, `name`, `age`, `sex`, `create_time`, `update_time`)
VALUES (#{id}, #{name}, #{age}, #{sex}, now(), now())
</insert>
<delete id="delete">
DELETE FROM `t_student`
WHERE `id` = #{id};
</delete>
<update id="update" parameterType="com.example.student.entity.StudentDO">
UPDATE `t_student`
SET `name` = #{name},
`age` = #{age},
`sex` = #{sex},
`update_time` = now()
WHERE `id` = #{id};
</update>
</mapper>
测试
尽管测试很简单,只是判断一下代码写的成不成功,但是也不能忽略。
package com.example.student.dao;
import com.example.student.entity.StudentDO;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import javax.annotation.Resource;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
@SpringBootTest
class StudentDAOTest {
@Resource
private StudentDAO studentDAO;
@Test
void testCount() {
assertEquals(1, studentDAO.count(null));
}
@Test
void testGetStudent() {
List<StudentDO> result = studentDAO.getStudent(null);
assertNotNull( result );
result.forEach( System.out::println );
}
@Test
void testInsert() {
StudentDO studentDO = new StudentDO();
studentDO.setName("xxx");
studentDO.setAge(10);
studentDO.setSex("男");
studentDAO.insert(studentDO);
}
@Test
void testDelete() {
studentDAO.delete("b4de711f900c11ea8fc654e1ad394a4a");
}
@Test
void testUpdate() {
StudentDO studentDO = new StudentDO();
studentDO.setId("b4de711f900c11ea8fc654e1ad394a4a");
studentDO.setName("yyy");
studentDO.setAge(20);
studentDO.setSex("女");
studentDAO.update(studentDO);
}
}
添加学生展示页面
添加插件
Bootstrap-table 显示表格
sweetalert 提示框(稍微好看点)
jquery-ui 拖动模态框等效果
插件具体如何使用可以去官网查看,这里只用最简单的一些功能。
添加一些js功能
- 初始化表格
- 弹出对话框
- 提示框样式修改
- ajax请求封装
- 时间格式化
- 模态框居中和拖拽功能
/**
* 渲染表格要用到的常用代码封装
*/
// 初始化表格
function initTable(node, url, pageList, queryParams, columns, toolbar = '#toolbar') {
node.bootstrapTable("destroy"); // 先销毁用来的表格再构造新的表格
node.bootstrapTable({
toolbar: toolbar, // 工具按钮用哪个容器
method: 'get', // 请求方式
url: url, // 请求路径
dataType: "json", // 服务器返回的数据类型
contentType: "application/json", // 发送到服务器的数据编码类型
striped: true, // 是否显示行间隔色
cache: false, // 是否使用缓存,默认为true,所以一般情况下需要设置一下这个属性(*)
pagination: true, // 是否显示分页(*)
sortable: false, // 是否启用排序
sortOrder: "asc", // 排序方式
sidePagination: "server", // 分页方式:client客户端分页,server服务端分页(*)
queryParamsType: "limit", // 设置为 ‘limit’ 则会发送符合 RESTFul 格式的参数
pageNumber: 1, // 初始化加载第一页,默认第一页
pageSize: 10, // 每页的记录行数(*)
pageList: pageList, // 可供选择的每页的行数(*)
showColumns: true, // 是否显示所有的列
showRefresh: true, // 是否显示刷新按钮
minimumCountColumns: 2, // 最少允许的列数
clickToSelect: true, // 是否启用点击选中行
showToggle:true, // 是否显示详细视图和列表视图的切换按钮
cardView: false, // 是否显示详细视图
detailView: false, // 是否显示父子表
uniqueId: "id", // 每一行的唯一标识,一般为主键列
dataField: "rows", // 这是返回的json数组的key.默认好像是"rows".这里只要前后端约定好就行
queryParams: queryParams,
responseHandler: result => {
if (result.success === false) {
switch (result.code) {
case 9001: swal("错误", "数据库错误", "error"); break;
case 9002: swal("错误", "参数错误", "error"); break;
case 9999: swal("错误", "系统错误", "error"); break;
}
return null;
} else {
return { total: result.module.total, rows: result.module.rows, };
}
},
columns: columns,
rowStyle: function (row, index) {
let classesArr = ['info', '#ffffff'];
let strClass = "";
if (index % 2 === 0) { // 偶数行
strClass = classesArr[0];
} else { // 奇数行
strClass = classesArr[1];
}
return { classes: strClass };
}// 隔行变色
});
}
// 弹出框
function dialog(message, callback) {
swal(message, {
buttons: {
true: "确定",
cancel: "取消"
},
}).then((value) => {
switch (value) {
case "true":
callback();
break;
default:
break;
}
});
}
// 修改提示框样式
function changeToolTip() {
$(function() {
$( document ).tooltip({
position: {
my: "center bottom-20",
at: "center top",
using: function( position, feedback ) {
$( this ).css( position );
$( "<div>" )
.addClass( "arrow" )
.addClass( feedback.vertical )
.addClass( feedback.horizontal )
.appendTo( this );
}
},
show: {
effect: "slideDown",
delay: 250
},
hide: {
effect: "explode",
delay: 250
}
});
$("select").on("select2:close", () => $("[role=tooltip]").remove());
});
}
// 无参数请求
function noParameterPostRequest(url, callback, method = "POST") {
$.ajax({
type: method,
url: url,
dataType: "json",
contentType : "application/json",
success: function (result) {
if (result.success === false) {
switch (result.code) {
case 9001: swal("错误", "数据库错误", "error"); break;
case 9002: swal("错误", "参数错误", "error"); break;
case 9999: swal("错误", "系统错误", "error"); break;
}
} else {
callback(result);
}
},
error: function () {
swal("错误", "404", "error");
}
});
}
// 有参数请求
function parameterPostRequest(url, data, callback, method = "POST") {
$.ajax({
type: method,
url: url,
dataType: "json",
data: JSON.stringify(data),
traditional: true,
contentType : "application/json",
success: function (result) {
if (result.success === false) {
switch (result.code) {
case 9001: swal("错误", "数据库错误", "error"); break;
case 9002: swal("错误", "参数错误", "error"); break;
case 9999: swal("错误", "系统错误", "error"); break;
}
} else {
callback(result);
}
},
error: function () {
swal("错误", "404", "error");
}
});
}
// UTC时间格式转换
function addZero(num) {
return num < 10 ? '0' + num : num;
}
function formatDateTime(date) {
let time = new Date(Date.parse(date));
let Y = time.getFullYear() + '-';
let M = this.addZero(time.getMonth() + 1) + '-';
let D = this.addZero(time.getDate()) + ' ';
let h = this.addZero(time.getHours()) + ':';
let m = this.addZero(time.getMinutes()) + ':';
let s = this.addZero(time.getSeconds());
return Y + M + D + h + m + s;
}
// 普通数据处理
function stringFormatter(value) {
return null === value ? "" : '<span title="'+ value +'">' + value +'</span>';
}
// 时间数据处理
function dateFormatter(value) {
return null === value ? "" : '<span title="'+ formatDateTime(value) +'">' + formatDateTime(value) +'</span>';
}
/**
* 修改模态框的操作
*/
// 修改模态框显示位置
function changeModalDialogLocation(node) {
node.on('show.bs.modal', function (e) {
// 关键代码,如没将modal设置为 block,则$modala_dialog.height() 为零
$(this).css('display', 'block');
let modalHeight=$(window).height() / 2 - node.find('.modal-dialog').height() / 2;
$(this).find('.modal-dialog').css({
'margin-top': modalHeight
});
});
}
// 设置模态框可拖动
function dragTheModalDialog() {
$(".modal").each((index, element) => changeModalDialogLocation($(element)));
// 在模态框出现后添加可拖拽功能
$(document).on("show.bs.modal", ".modal", function() {
// draggable 属性规定元素是否可拖动
$(this).draggable({
handle: ".modal-header", // 只能点击头部拖动
cursor: 'move' // 光标呈现为指示链接的指针(一只手),
});
$(this).css("overflow", "hidden"); // 防止出现滚动条,出现的话,你会把滚动条一起拖着走的
});
}
修改页面
用来那个只有登陆成功的页面就改成我们显示学生信息的页面吧。
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>学生信息</title>
<!-- Bootstrap CSS-->
<link rel="stylesheet" href="../../static/css/lib/bootstrap3.4.1.min.css" th:href="@{/css/lib/bootstrap3.4.1.min.css}">
<!-- Bootstrap-table CSS-->
<link rel="stylesheet" href="../../static/css/lib/bootstrap-table.min.css" th:href="@{/css/lib/bootstrap-table.min.css}">
<!-- jquery-ui CSS-->
<link rel="stylesheet" href="../../static/css/lib/jquery-ui.min.css" th:href="@{/css/lib/jquery-ui.min.css}">
<!-- theme stylesheet-->
<link rel="stylesheet" href="../../static/css/table.css" th:href="@{/css/table.css}">
</head>
<body onload="init();">
<div class="panel-body" style="padding-bottom:0;">
<div class="panel panel-default">
<div class="panel-heading">查询条件</div>
<div class="panel-body">
<div class="form-group" style="margin-top:15px">
<div class="row row-gap">
<label class="control-label col-sm-2 label-font" for="txt_search_name" title="姓名">姓名</label>
<div class="col-sm-3">
<input type="text" class="form-control" id="txt_search_name">
</div>
<div class="col-sm-4" style="text-align:left;">
<button type="button" style="margin-left:50px" id="btn_filter" class="btn btn-primary" onclick="filter();">过滤</button>
<button type="button" style="margin-left:50px" id="btn_reset_filter" class="btn btn-primary" onclick="init();">重置过滤</button>
</div>
</div>
</div>
</div>
<div id="toolbar" class="btn-group">
<button id="btn_add" type="button" class="btn btn-default" onclick="insert();">
<span class="glyphicon glyphicon-plus" aria-hidden="true"></span>添加学生
</button>
</div>
<table id="table"></table>
</div>
<!-- JavaScript files-->
<!-- jquery.js -->
<script src="../../static/js/lib/jquery.min.js" th:src="@{/js/lib/jquery.min.js}"></script>
<!-- Bootstrap.js -->
<script src="../../static/js/lib/bootstrap3.4.1.min.js" th:src="@{/js/lib/bootstrap3.4.1.min.js}"></script>
<!-- Bootstrap-table.js -->
<script src="../../static/js/lib/bootstrap-table.min.js" th:src="@{/js/lib/bootstrap-table.min.js}"></script>
<script src="../../static/js/lib/bootstrap-table-zh-CN.min.js" th:src="@{/js/lib/bootstrap-table-zh-CN.min.js}"></script>
<!-- sweetalert2.js -->
<script src="../../static/js/lib/sweetalert.min.js" th:src="@{/js/lib/sweetalert.min.js}"></script>
<script src="../../static/js/lib/es6-promise.auto.min.js" th:src="@{/js/lib/es6-promise.auto.min.js}"></script>
<!-- jquery-ui.js -->
<script src="../../static/js/lib/jquery-ui.min.js" th:src="@{/js/lib/jquery-ui.min.js}"></script>
<script src="../../static/js/common.js" th:src="@{/js/common.js}"></script>
<script src="../../static/js/dragModel.js" th:src="@{/js/dragModel.js}"></script>
<script>
function init() {
}
function filter() {
}
function insert() {
}
</script>
</body>
</html>
运行结果:
添加增删改查功能
前戏做足了,要开始到高潮部分了。
显示数据
添加工具类
我们为了实现分页,先添加一些工具类,也是为了配合Bootstrap-table插件的使用。
这里total字段是固定的,rows字段其实不一定要叫rows也可以叫别的,和刚刚写的初始化表格里面的设置是对应的。
package edu.yctc.erpsystem.util;
import java.util.List;
/**
* 分页存放工具类
*
* @author xiaotao
*/
public class PageUtils<T> {
/**
* 数据总数
*/
private int total;
/**
* 数据
*/
private List<T> rows;
public PageUtils(int total, List<T> rows) {
this.total = total;
this.rows = rows;
}
public int getTotal() {
return total;
}
public void setTotal(int total) {
this.total = total;
}
public List<T> getRows() {
return rows;
}
public void setRows(List<T> rows) {
this.rows = rows;
}
@Override
public String toString() {
return "PageUtils{" +
"total=" + total +
", rows=" + rows +
'}';
}
}
这个是帮助判断前端传递的参数的。
package edu.yctc.erpsystem.util;
import java.util.Map;
/**
* 处理参数
*
* @author xiaotao
*/
public class ParamUtils {
/** list 为 All */
private static final String NAN = "NaN";
/** 偏移量 */
private static final String OFFSET = "offset";
/** 步长 */
private static final String LIMIT = "limit";
/**
* 验证入参正确性
*
* @param params 参数
* @return 是否正确
*/
public static Boolean validation(Map<String, Object> params) {
try {
if (NAN.equals(params.get(OFFSET))) {
params.remove(OFFSET);
params.remove(LIMIT);
return true;
}
params.replace(OFFSET, Integer.valueOf((String)params.get(OFFSET)));
params.replace(LIMIT, Integer.valueOf((String)params.get(LIMIT)));
return true;
} catch (Exception e) {
return false;
}
}
}
编写service层
package com.example.student.service;
import com.example.student.entity.ResultDO;
import com.example.student.entity.StudentDO;
import com.example.student.util.PageUtils;
import java.util.Map;
/**
* 学生逻辑接口
*
* @author xiaotao
*/
public interface StudentInterService {
/**
* 获得所有学生信息
*
* @param params 过滤参数
* @return 学生信息
*/
ResultDO<PageUtils<StudentDO>> getStudent(Map<String, Object> params);
}
这里就不做参数检验了,放到控制层做检验。
package com.example.student.service.impl;
import com.example.student.constant.ResultCode;
import com.example.student.dao.StudentDAO;
import com.example.student.entity.ResultDO;
import com.example.student.entity.StudentDO;
import com.example.student.service.StudentInterService;
import com.example.student.util.PageUtils;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
/**
* 学生逻辑实现
*
* @author xiaotao
*/
@ComponentScan({"com.example.student.dao"})
@Service("studentService")
public class StudentServiceImpl implements StudentInterService {
@Resource
private StudentDAO studentDAO;
@Override
public ResultDO<PageUtils<StudentDO>> getStudent(Map<String, Object> params) {
List<StudentDO> result = studentDAO.getStudent(params);
if (result == null) {
return new ResultDO<>(false, ResultCode.DB_ERROR, ResultCode.MSG_DB_ERROR, null);
}
return new ResultDO<>(true, ResultCode.SUCCESS, ResultCode.MSG_SUCCESS, new PageUtils<>(studentDAO.count(params), result));
}
}
编写rest数据接口
package com.example.student.controller.rest;
import com.example.student.entity.ResultDO;
import com.example.student.entity.StudentDO;
import com.example.student.util.PageUtils;
import java.util.Map;
/**
* 学生数据接口
*
* @author xiaotao
*/
public interface StudentRestController {
/**
* 获得所有学生信息
*
* @param params 过滤参数
* @return 学生信息
*/
ResultDO<PageUtils<StudentDO>> getStudent(Map<String, Object> params);
}
代码挺简单的,要注意一下@RequestParam
不要忘记了。
package com.example.student.controller.rest.impl;
import com.example.student.constant.ResultCode;
import com.example.student.controller.rest.StudentRestController;
import com.example.student.entity.ResultDO;
import com.example.student.entity.StudentDO;
import com.example.student.service.StudentInterService;
import com.example.student.util.PageUtils;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.Map;
import static com.example.student.util.ParamUtils.validation;
/**
* 学生数据接口实现
*
* @author xiaotao
*/
@RestController
@ComponentScan({"com.example.student.service"})
@RequestMapping("/student")
public class StudentRestControllerImpl implements StudentRestController {
@Resource
private StudentInterService studentService;
@Override
@GetMapping("getStudent")
public ResultDO<PageUtils<StudentDO>> getStudent(@RequestParam Map<String, Object> params) {
if (!validation(params)) {
return new ResultDO<>(false, ResultCode.PARAMETER_INVALID, ResultCode.MSG_PARAMETER_INVALID, null);
}
return studentService.getStudent(params);
}
}
编写js渲染代码
这里初始化表格里面field
对应的是rest传过来的StudentDO的字段名字,title
是前端显示的内容,width
为列宽,可以用formatter
给列添加样式(看性别那一列)。
<script>
/** 初始化 */
let $table = $('#table');
changeToolTip();
// 服务器分页获取数据
function getServerPaging(node, url, queryParams) {
initTable(node, url, [10, 25, 50, 100, "All"], queryParams, [{
checkbox: true
}, {
field: 'name',
title: '姓名',
width: "170px",
formatter: stringFormatter
}, {
field: 'age',
title: '年龄',
width: '70px',
formatter: stringFormatter
}, {
field: 'sex',
title: '性别',
width: '70px',
align: "center",
formatter: value => null === value ? "" : "男" === value ? '<span title="男" class="label label-success">男</span>' : '<span title="女" class="label label-warning">女</span>'
}, {
field: 'createTime',
title: '创建时间',
width: "170px",
formatter: dateFormatter
}, {
field: 'updateTime',
title: '修改时间',
width: "170px",
formatter: dateFormatter
}]);
}
function init() {
getServerPaging($table, "/student/getStudent", params => {
return { limit: params.limit, offset: params.offset, sort: "create_time", order: "DESC" };
});
}
function filter() {
}
function insert() {
}
</script>
运行了一下发现少了点字体文件
加上后的运行结果:
提示效果:
这里的两个数据是dao层测试的时候加上去的。。。
添加记录
编写service层
/**
* 插入记录
*
* @param studentDO 学生实体
* @return 是否成功
*/
ResultDO<Void> insert(StudentDO studentDO);
@Override
public ResultDO<Void> insert(StudentDO studentDO) {
if (StringUtils.isBlank(studentDO.getName())) {
return new ResultDO<>(false, ResultCode.PARAMETER_INVALID, ResultCode.MSG_PARAMETER_INVALID, null);
}
try {
studentDAO.insert(studentDO);
} catch (Exception e) {
return new ResultDO<>(false, ResultCode.DB_ERROR, ResultCode.MSG_DB_ERROR, null);
}
return new ResultDO<>(true, ResultCode.SUCCESS, ResultCode.MSG_SUCCESS, null);
}
编写rest数据接口
/**
* 插入记录
*
* @param studentDO 学生实体
* @return 是否成功
*/
ResultDO<Void> insert(StudentDO studentDO);
@Override
@PostMapping("insert")
public ResultDO<Void> insert(@RequestBody StudentDO studentDO) {
if (StringUtils.isBlank(studentDO.getName())) {
return new ResultDO<>(false, ResultCode.PARAMETER_INVALID, ResultCode.MSG_PARAMETER_INVALID, null);
}
return studentService.insert(studentDO);
}
编写js渲染代码
我们使用模态框输入信息,单击添加按钮当然就是打开模态框了。
<div id="toolbar" class="btn-group">
<button id="btn_add" type="button" class="btn btn-default" data-toggle="modal" data-target="#addModal">
<span class="glyphicon glyphicon-plus" aria-hidden="true"></span>添加学生
</button>
</div>
模态框也很简单
<!-- 模态框(Modal) 新增 -->
<div class="modal fade" id="addModal" tabindex="-1" role="dialog" aria-labelledby="addModalLabel" aria-hidden="true">
<div class="modal-dialog" style="min-width: 800px">
<div class="modal-content">
<div class="modal-header">
<h2 class="modal-title text-center" id="addModalLabel">
添加学生信息
</h2>
</div>
<div class="modal-body">
<form class="form-horizontal" role="form" onsubmit="return false;">
<div class="form-group has-success">
<label class="col-sm-2 control-label label-font" for="insert_input_name">姓名</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="insert_input_name" title="不能为空">
</div>
</div>
<div class="form-group has-success">
<label class="col-sm-2 control-label label-font" for="insert_input_age">年龄</label>
<div class="col-sm-10">
<input type="number" class="form-control" id="insert_input_age">
</div>
</div>
<div class="form-group has-success">
<label class="col-sm-2 control-label label-font" for="insert_input_sex">性别</label>
<div class="col-sm-10">
<select class="form-control" id="insert_input_sex">
<option value="男">男</option>
<option value="女">女</option>
</select>
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-success" onclick="insert();">添加</button>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal -->
</div>
添加函数里面简单的判断了一下输入的值的合法性,插入成功后刷新表格信息。
dragTheModalDialog();
function insert() {
let data = {
name: $('#insert_input_name').val(),
age: $('#insert_input_age').val(),
sex: $('#insert_input_sex').val()
};
if ("" === data.name) {
swal("操作提示", "姓名不能为空", "info");
} else{
parameterPostRequest("/student/insert", data, () => {
$('#addModal').modal('hide');
swal("正确", "添加成功", "success");
init();
});
}
}
运行效果:
查询
现在实现这个功能已经很简单了,后端已经建好了。
过滤是模糊查询,重置过滤可以说是重新初始化。
function filter() {
let data = {
name: $("#txt_search_name").val()
};
if ("" === data.name) {
swal("操作提示", "请填写过滤参数", "info");
return;
}
getServerPaging($table, "/student/getStudent", params => {
return { limit: params.limit, offset: params.offset, sort: "create_time", order: "DESC", name: data.name};
});
}
运行效果:
删除
编写service层
/**
* 删除
*
* @param id 记录id
* @return 是否成功
*/
ResultDO<Void> delete(String id);
@Override
public ResultDO<Void> delete(String id) {
if (StringUtils.isBlank(id)) {
return new ResultDO<>(false, ResultCode.PARAMETER_INVALID, ResultCode.MSG_PARAMETER_INVALID, null);
}
try {
studentDAO.delete(id);
} catch (Exception e) {
return new ResultDO<>(false, ResultCode.DB_ERROR, ResultCode.MSG_DB_ERROR, null);
}
return new ResultDO<>(true, ResultCode.SUCCESS, ResultCode.MSG_SUCCESS, null);
}
编写rest数据接口
/**
* 删除
*
* @param studentDO 学生实体
* @return 是否成功
*/
ResultDO<Void> delete(StudentDO studentDO);
@Override
@PostMapping("delete")
public ResultDO<Void> delete(@RequestBody StudentDO studentDO) {
if (StringUtils.isBlank(studentDO.getId())) {
return new ResultDO<>(false, ResultCode.PARAMETER_INVALID, ResultCode.MSG_PARAMETER_INVALID, null);
}
return studentService.delete(studentDO.getId());
}
编写js渲染代码
这里我们稍微修改一下initTable里面的参数:
function operateFormatter(value, row, index) { // 赋予的参数
return [
'<button class="btn btn-primary view" data-toggle="modal" data-target="#alterModal" οnclick="initUpdate('+ index +');">编辑</button> '+
'<button class="btn btn-danger view" οnclick="deleteOne('+ index +');">删除</button>'
].join('');
}
这里的$table.bootstrapTable('getData')
可以获取到表格的所有数据,具体看官网。
删除成功了也还是刷新表格。
function deleteOne() {
dialog("确定删除吗?", () => {
let data = { id: $table.bootstrapTable('getData')[index].id };
parameterPostRequest("/student/delete", data, () => {
swal("正确", "删除成功", "success");
init();
});
});
}
function initUpdate() {
}
运行效果:
修改
编写service层
/**
* 修改实体
*
* @param studentDO 学生实体
* @return 是否成功
*/
ResultDO<Void> update(StudentDO studentDO);
@Override
public ResultDO<Void> update(StudentDO studentDO) {
if (StringUtils.isBlank(studentDO.getId()) || StringUtils.isBlank(studentDO.getName())) {
return new ResultDO<>(false, ResultCode.PARAMETER_INVALID, ResultCode.MSG_PARAMETER_INVALID, null);
}
try {
studentDAO.update(studentDO);
} catch (Exception e) {
return new ResultDO<>(false, ResultCode.DB_ERROR, ResultCode.MSG_DB_ERROR, null);
}
return new ResultDO<>(true, ResultCode.SUCCESS, ResultCode.MSG_SUCCESS, null);
}
编写rest数据接口
/**
* 修改实体
*
* @param studentDO 学生实体
* @return 是否成功
*/
ResultDO<Void> update(StudentDO studentDO);
@Override
@PostMapping("update")
public ResultDO<Void> update(@RequestBody StudentDO studentDO) {
if (StringUtils.isBlank(studentDO.getId()) || StringUtils.isBlank(studentDO.getName())) {
return new ResultDO<>(false, ResultCode.PARAMETER_INVALID, ResultCode.MSG_PARAMETER_INVALID, null);
}
return studentService.update(studentDO);
}
编写js渲染代码
编辑的模态框
<!--模态框(Modal) 编辑-->
<div class="modal fade" id="alterModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog" style="min-width: 800px">
<div class="modal-content">
<div class="modal-header">
<h2 class="modal-title text-center" id="alterModalLabel">
编辑学生信息
</h2>
</div>
<div class="modal-body">
<form class="form-horizontal" role="form" onsubmit="return false;">
<div class="form-group has-success">
<label class="col-sm-2 control-label label-font" for="alert_input_name">姓名</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="alert_input_name" title="不能为空">
</div>
</div>
<div class="form-group has-success">
<label class="col-sm-2 control-label label-font" for="alert_input_age">年龄</label>
<div class="col-sm-10">
<input type="number" class="form-control" id="alert_input_age">
</div>
</div>
<div class="form-group has-success">
<label class="col-sm-2 control-label label-font" for="alert_input_sex">性别</label>
<div class="col-sm-10">
<select class="form-control" id="alert_input_sex">
<option value="男">男</option>
<option value="女">女</option>
</select>
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" onclick="alter()">编辑</button>
</div>
</div> <!--/.modal-content -->
</div><!--/.modal-->
</div>
// alter记录id
let alterId;
function initUpdate(index) {
let rows = $table.bootstrapTable('getData');
$('#alert_input_name').val(rows[index].name);
$('#alert_input_age').val(rows[index].age);
$('#alert_input_sex').val(rows[index].sex);
alterId = rows[index].id;
}
function alter() {
let data = {
id: alterId,
name: $('#alert_input_name').val(),
age: $('#alert_input_age').val(),
sex: $('#alert_input_sex').val()
};
if ("" === data.id) {
swal("操作提示", "用户不存在", "info");
} else if ("" === data.name) {
swal("操作提示", "姓名不能为空", "info");
} else if (data.age <= 0 || data.age >= 200) {
swal("操作提示", "年龄不合法", "info");
} else {
parameterPostRequest("/student/update", data, () => {
$('#alterModal').modal('hide');
swal("正确", "编辑成功", "success");
init();
});
}
}
运行结果:
百度云链接
项目代码 百度云链接:https://pan.baidu.com/s/1QoUR61paTpUBii5piBHCYw
提取码:xy7f