使用SpringBoot和MyBatis实现学生管理
程序员文章站
2022-03-09 07:57:42
...
学生管理接口
package com.yangzc.studentboot.student.controller;
import com.yangzc.studentboot.common.annotation.ApiJsonObject;
import com.yangzc.studentboot.common.annotation.ApiJsonProperty;
import com.yangzc.studentboot.common.domain.ActionResult;
import com.yangzc.studentboot.common.utils.DownloadUtil;
import com.yangzc.studentboot.student.dao.StudentDOMapper;
import com.yangzc.studentboot.student.domain.StudentDO;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.util.ResourceUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.*;
/**
* @Author: yangzc
* @Description:
* @Date: Created on 7:59 2019/12/24
* @Modified By:
*/
@Controller
@RequestMapping("/stu/list")
public class StudentController {
private String prefix = "student";
@Value("${studentboot.uploadPath}")
private String savePath;
@Autowired
StudentDOMapper studentDOMapper;
@GetMapping()
@RequiresPermissions("stu:list")
String student() {
return prefix + "/list";
}
@PostMapping(value = "/welcome", produces = MediaType.APPLICATION_JSON_VALUE)
@ApiOperation(value = "学生列表", notes = "根据指定的页码和行数返回学生列表")
@RequiresPermissions("stu:list")
@ResponseBody
public ActionResult getStudents(@ApiJsonObject(name = "params", value = {
@ApiJsonProperty(key = "page", example = "1", description = "页码"),
@ApiJsonProperty(key = "rows", example = "5", description = "行数"),
@ApiJsonProperty(key = "begin", example = "0", description = "开始"),
@ApiJsonProperty(key = "sort", example = "sno", description = "排序字段"),
@ApiJsonProperty(key = "order", example = "desc", description = "排序"),
}) @RequestBody Map<String,Object> params) {
Map<String,Object> data = new HashMap<String,Object>();
data.put("total",studentDOMapper.count());
List<StudentDO> students = studentDOMapper.list(params);
data.put("rows",students);
ActionResult result = new ActionResult(data);
return result;
}
/**
* 学生编辑
* @param sid
* @return
*/
@GetMapping(value = "/edit/{sid}", produces = MediaType.APPLICATION_JSON_VALUE)
@ApiOperation(value = "学生信息加载", notes = "根据学号获取该学生的信息")
@ApiImplicitParam(name = "sid", value = "学号", dataType = "int", paramType = "path", example = "1001")
@ResponseBody
public ActionResult loadStudent(@PathVariable Integer sid){
ActionResult result = null;
StudentDO student = studentDOMapper.selectByPrimaryKey(sid);
result = ActionResult.ok(student);
return result;
}
/**
* 学生保存
* @param stu
* @return
*/
@PostMapping(value = "/save", produces = MediaType.APPLICATION_JSON_VALUE)
@ApiOperation(value = "学生信息保存", notes = "将输入的学生信息保存到数据库")
@ResponseBody
public ActionResult saveStudent(StudentDO stu){
ActionResult result = null;
if(stu.getSno()==null||stu.getSno()==0){
studentDOMapper.insert(stu);
} else {
studentDOMapper.updateByPrimaryKey(stu);
}
result = ActionResult.ok();
return result;
}
/**
* 学生删除
* @param sid
* @return
*/
@ApiOperation(value = "删除学生信息", notes = "根据学号删除该学生的信息")
@ApiImplicitParam(name = "sid", value = "学号", dataType = "int", paramType = "path", example = "1001")
@DeleteMapping(value = "/delete/{sid}", produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public ActionResult delStudent(@PathVariable Integer sid){
ActionResult result = null;
studentDOMapper.deleteByPrimaryKey(sid);
result = ActionResult.ok();
return result;
}
/**
* 文件上传
* @param file
* @param req
* @return
*/
@ApiOperation(value = "头像上传", notes = "文件上传")
@ApiImplicitParam(name = "source", value = "图片", dataType = "__file", required = true, paramType = "form")
@PostMapping(value = "/upload/file", produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public ActionResult uploadFile(@RequestParam("source") MultipartFile file, HttpServletRequest req) {
ActionResult result = null;
try {
// 截取不同类型的文件需要自行判断
String filename = file.getOriginalFilename();
if (!file.isEmpty()) {
String extName = filename.substring(filename.indexOf("."));// 取文件格式后缀名
String uuid = UUID.randomUUID().toString().replace("-", "");
// 新名称
String newName = uuid + extName;// 在这里用UUID来生成新的文件夹名字,这样就不会导致重名
file.transferTo(new File(savePath+"/"+newName));
result = ActionResult.ok("/files/"+newName);
}
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
/**
* 导出学生列表
* @return
*/
@PostMapping(value = "/export")
@ResponseBody
public ActionResult export(){
ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletResponse response = requestAttributes.getResponse();
//1.创建工作簿
//String path = servletContext.getRealPath("/");
//path = path+"/make/students.xls"; //得到模板文件所在位置
File file = null;
try {
file = ResourceUtils.getFile("classpath:make/students.xls");
} catch (FileNotFoundException e) {
e.printStackTrace();
return new ActionResult(-1,"出现异常",null);
}
InputStream is = null; //根据文件,得到指定的文件流
try {
is = new FileInputStream(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
return new ActionResult(-1,"出现异常",null);
}
//根据文件流,加载指定的工作簿
//它只能操作excel2003版本
Workbook wb = null;
try {
wb = new HSSFWorkbook(is);
} catch (IOException e) {
e.printStackTrace();
return new ActionResult(-1,"出现异常",null);
}
//2.读取工作表
Sheet sheet = wb.getSheetAt(0); //0代表工作表的下标
//抽取出一些公用变量
Row nRow=null;
Cell nCell = null;
int rowNo=1;//行号
int cellNo=0;//列号
//===========================================数据内容
nRow = sheet.getRow(rowNo);//读取第2行
//
CellStyle snoCellStyle = nRow.getCell(cellNo++).getCellStyle();//读取单元格的样式
String str = nRow.getCell(cellNo).getStringCellValue();//读取单元格的内容
System.out.println(str);
CellStyle snameCellStyle = nRow.getCell(cellNo++).getCellStyle();//读取单元格的样式
CellStyle isMaleCellStyle = nRow.getCell(cellNo++).getCellStyle();//读取单元格的样式
CellStyle birthCellStyle = nRow.getCell(cellNo++).getCellStyle();//读取单元格的样式
List<StudentDO> list = studentDOMapper.selectAll();
//遍历学生列表
for(StudentDO stu :list){
//产生一个新行
nRow = sheet.createRow(rowNo++);
//nRow.setHeightInPoints(24f);//设置行高
cellNo=0;
nCell = nRow.createCell(cellNo++);//创建单元格
nCell.setCellValue(stu.getSno());//设置单元格内容
nCell.setCellStyle(snoCellStyle); //设置单元格样式
nCell = nRow.createCell(cellNo++);//创建单元格
nCell.setCellValue(stu.getSname());//设置单元格内容
nCell.setCellStyle(snameCellStyle); //设置单元格样式
nCell = nRow.createCell(cellNo++);//创建单元格
nCell.setCellValue(stu.getGender());//设置单元格内容
nCell.setCellStyle(isMaleCellStyle); //设置单元格样式
nCell = nRow.createCell(cellNo++);//创建单元格
nCell.setCellValue(stu.getBirth());//设置单元格内容
nCell.setCellStyle(birthCellStyle); //设置单元格样式
}
//输出
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();//内存的缓冲区
try {
wb.write(byteArrayOutputStream);
} catch (IOException e) {
e.printStackTrace();
}
DownloadUtil downloadUtil = new DownloadUtil();
Calendar cal = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
//response.setHeader("Transfer-Encoding", "chunked");
String returnName = "students" + sdf.format(cal.getTime()) + ".xls";
try {
downloadUtil.download(byteArrayOutputStream, response, returnName);
} catch (IOException e) {
e.printStackTrace();
return new ActionResult(-1,"出现异常",null);
}
return null;
}
/**
* 导入学生列表
* @param file
* @return
* @throws Exception
*/
@PostMapping("import")
@ResponseBody
public ActionResult upload(@PathVariable("file") MultipartFile file) throws Exception {
HSSFWorkbook hssfWorkbook = new HSSFWorkbook(file.getInputStream());
List<StudentDO> getData = readOldExcel(hssfWorkbook);
if (getData == null) {
return new ActionResult(-1,"解析文件失败",null);
}
file.getInputStream().close();
for(StudentDO stu:getData) {
studentDOMapper.insert(stu);
}
return ActionResult.ok(getData);
}
//处理2007之前的excel
private List<StudentDO> readOldExcel(HSSFWorkbook hssfWorkbook) {
List<StudentDO> students = new ArrayList<StudentDO>();
HSSFSheet sheetAt = hssfWorkbook.getSheetAt(0);
HSSFCell cell = null;
HSSFRow row = null;
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
for (int i = sheetAt.getFirstRowNum()+1; i < sheetAt.getPhysicalNumberOfRows(); i++) {
row = sheetAt.getRow(i);
if (row == null) {
continue;
}
Object[] objects = new Object[row.getLastCellNum()];
for (int j = row.getFirstCellNum(); j < row.getLastCellNum(); j++) {
cell = row.getCell(j);
switch (cell.getCellTypeEnum()) {
case STRING:
objects[j] = cell.getStringCellValue();
System.out.println(cell.getStringCellValue());
break;
case _NONE:
objects[j] = "";
break;
case BOOLEAN:
objects[j] = cell.getBooleanCellValue();
System.out.println(cell.getBooleanCellValue());
break;
case NUMERIC:
//处理double类型的 1.0===》1
DecimalFormat df = new DecimalFormat("0");
String s = df.format(cell.getNumericCellValue());
objects[j] = s;
System.out.println(s);
break;
default:
objects[j] = cell.toString();
}
}
//处理数据
if (objects != null) {
StudentDO stu = new StudentDO();
stu.setSname((String) objects[1]);
stu.setGender((String)objects[2]);
stu.setBirth(row.getCell(3).getDateCellValue());
students.add(stu);
}
}
return students;
}
}
学生管理页面(html)
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>学生管理系统</title>
<link rel="stylesheet" type="text/css" href="/bootstrap/bootstrap.css"/>
<link rel="stylesheet" type="text/css" href="/bootstrap-datetimepicker/bootstrap-datetimepicker.css"/>
<link rel="stylesheet" href="/bootstrap-table/bootstrap-table.css">
<link rel="stylesheet" href="/bootstrap-fileinput/fileinput.css">
<link rel="stylesheet" href="/bootstrap-fileinput/fileinput-rtl.css">
<script src="/jquery/jquery.js"></script>
<script src="/bootstrap/bootstrap.js" type="text/javascript" charset="utf-8"></script>
<script src="/bootstrap-datetimepicker/bootstrap-datetimepicker.js" type="text/javascript" charset="utf-8"></script>
<script src="/bootstrap-datetimepicker/bootstrap-datetimepicker.zh-CN.js" type="text/javascript" charset="utf-8"></script>
<script src="/bootstrap-table/bootstrap-table.js"></script>
<script src="/bootstrap-table/bootstrap-table-zh-CN.js"></script>
<script src="/bootstrap-fileinput/fileinput.js"></script>
<script src="/bootstrap-fileinput/zh.js"></script>
<script src="/app/FileSaver.js"></script>
<script src="/app/student.js"></script>
<script type="text/javascript">
$(function(){
$('.form_date').datetimepicker({
language: 'zh-CN',
weekStart: 1,
todayBtn: 1,
autoclose: 1,
todayHighlight: 1,
startView: 2,
minView: 2,
forceParse: 0,
});
initMainTable();
})
</script>
<script>
$(document).ready(function() {
$("#input-b9").fileinput({
showPreview: false,
showUpload: true,
elErrorContainer: '#kartik-file-errors',
allowedFileExtensions: ["xls","xlsx"],
uploadUrl: 'import'
});
});
</script>
</head>
<body class="bg-info">
<div>
<table id="grid" class="table" data-toolbar=".toolbar"></table>
</div>
<div id="toolbar" class="toolbar">
<button type="button" class="btn btn-primary" onclick="add();">
<span class="glyphicon glyphicon-plus" aria-hidden="true"></span> 添加
</button>
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#exampleModal">
<span class="glyphicon glyphicon-import" aria-hidden="true"></span> 导入
</button>
<button type="button" class="btn btn-primary" onclick="exportData();">
<span class="glyphicon glyphicon-export" aria-hidden="true"></span> 导出
</button>
</div>
<!-- Modal -->
<div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Modal title</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<div class="file-loading">
<input id="input-b9" name="file" multiple type="file">
</div>
<div id="kartik-file-errors"></div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary" title="Your custom upload logic">Save</button>
</div>
</div>
</div>
</div>
<!-- 模态框(Modal) -->
<div class="modal fade" id="edit" 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>
<h3 class="modal-title" id="subject"></h3>
</div>
<div class="modal-body">
<form role="form" id="register">
<div class="form-group" id="first">
<label for="sid">学号</label>
<input type="text" class="form-control" id="sid" name="sno" readonly>
</div>
<div class="form-group">
<label for="sname">姓名</label>
<input type="text" class="form-control" id="sname" name="sname" placeholder="请输入姓名">
</div>
<label>性別</label>
<div class="form-group">
<label class="radio-inline">
<input type="radio" name="gender" id="male" value="1" checked> 靓仔
</label>
<label class="radio-inline">
<input type="radio" name="gender" id="female" value="0"> 美女
</label>
</div>
<div class="form-group">
<label for="birth">生日</label>
<div class="input-group date form_date" data-date="" data-date-format="yyyy MM dd" data-link-field="birth" data-link-format="yyyy-mm-dd">
<input name="birth" id="birth" class="form-control" type="text" value="" readonly>
<span class="input-group-addon">
<span class="glyphicon glyphicon-remove"></span>
</span>
<span class="input-group-addon">
<span class="glyphicon glyphicon-calendar"></span>
</span>
</div>
</div>
<div class="form-group">
<label for="photo">上传头像</label>
<input type="file" id="photo" name="photo">
<p class="help-block">请上传jpg或者png格式的文件!</p>
</div>
<div class="form-group">
<button type="button" class="btn btn-default" onclick="upload();">
<span class="glyphicon glyphicon-upload" aria-hidden="true"></span> 上传
</button>
</div>
<div hidden="hidden">
<input type="text" name="photoUrl" id="filePath" value="/img/default.png"/>
</div>
<div class="form-group">
<img width="120" height="120" src="/img/default.png" id="photo2"/>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">关闭</button>
<button type="button" class="btn btn-primary" onclick="save();">保存</button>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
</body>
</html>
学生管理页面(js)
var $table;
var rows = 5;
function initMainTable() { //初始化bootstrap-table的内容
//记录页面bootstrap-table全局变量$table,方便应用
var queryUrl = 'welcome';
$table = $('#grid').bootstrapTable({
url: queryUrl, //请求后台的URL(*)
method: 'POST', //请求方式(*)
toolbar: '.toolbar', //工具按钮用哪个容器
striped: true, //是否显示行间隔色
cache: false, //是否使用缓存,默认为true,所以一般情况下需要设置一下这个属性(*)
pagination: true, //是否显示分页(*)
sortable: true, //是否启用排序
sortOrder: "asc", //排序方式
sortName: "sno",
sidePagination: "server", //分页方式:client客户端分页,server服务端分页(*)
pageNumber: 1, //初始化加载第一页,默认第一页,并记录
pageSize: rows, //每页的记录行数(*)
pageList: [10, 25, 50, 100], //可供选择的每页的行数(*)
search: false, //是否显示表格搜索
strictSearch: true,
showColumns: true, //是否显示所有的列(选择显示的列)
showRefresh: true, //是否显示刷新按钮
minimumCountColumns: 2, //最少允许的列数
clickToSelect: true, //是否启用点击选中行
//height: 500, //行高,如果没有设置height属性,表格自动根据记录条数觉得表格高度
uniqueId: "sno", //每一行的唯一标识,一般为主键列
showToggle: true, //是否显示详细视图和列表视图的切换按钮
cardView: false, //是否显示详细视图
detailView: false, //是否显示父子表
//得到查询的参数
queryParams : function (params) {
//这里的键的名字和控制器的变量名必须一直,这边改动,控制器也需要改成一样的
var temp = {
rows: params.limit, //页面大小
page: (params.offset / params.limit) + 1, //页码
begin: params.offset,
sort: params.sort, //排序列名
order: params.order //排位命令(desc,asc)
};
return JSON.stringify(temp);
},
columns: [{
checkbox: true,
visible: true //是否显示复选框
}, {
field: 'sno',
title: '学号',
sortable: true
}, {
field: 'sname',
title: '姓名',
sortable: true
}, {
field: 'gender',
title: '性别',
sortable: true,
formatter: genderFormatter
}, {
field: 'birth',
title: '生日'
}, {
field:'sno',
title: '操作',
width: 120,
align: 'center',
valign: 'middle',
formatter: actionFormatter
}, ],
onLoadSuccess: function () {
},
onLoadError: function () {
alert("数据加载失败!");
},
onDblClickRow: function (row, $element) {
var id = row.sno;
edit(id);
},
responseHandler: responseHandler,
});
};
function actionFormatter(value, row, index) { //操作栏的格式化
var id = value;
var result = "";
result += "<a href='javascript:;' class='btn btn-xs green' οnclick=\"view(" + id + ")\" title='查看'><span class='glyphicon glyphicon-search'></span></a>";
result += "<a href='javascript:;' class='btn btn-xs blue' οnclick=\"edit(" + id + ")\" title='编辑'><span class='glyphicon glyphicon-pencil'></span></a>";
result += "<a href='javascript:;' class='btn btn-xs red' οnclick=\"del(" + id + ")\" title='删除'><span class='glyphicon glyphicon-remove'></span></a>";
return result;
}
/**
* 获取返回的数据的时候做相应处理,让bootstrap table认识我们的返回格式
* @param {Object} res
*/
function responseHandler(res) {
return {
"rows": res.data.rows, // 具体每一个bean的列表
"total": res.data.total // 总共有多少条返回数据
}
}
//性别字段格式化
function genderFormatter(value) {
var gender;
if (value == '女' || value == '0') {
color = 'Red';
gender = '小姐姐';
}
else if (value == '男' || value == '1') {
color = 'Blue';
gender = '大帅哥';
}
else { color = 'Yellow'; }
return '<div style="color: ' + color + '">' + gender + '</div>';
}
function add(){
$("#subject").text("注册学生信息");
$("#first").hide();
$("#register")[0].reset();
$("#photo2").attr("src","/img/default.png");
//$("#edit").css("display","block");
$('.form_date').datetimepicker("setDate", new Date());
$('#edit').modal('show');
}
function edit(sid){
$("#register")[0].reset();
$("#subject").text("修改学生信息");
$("#first").show();
$("#photo2").attr("src","/img/default.png");
//var sid = $(e).parent().siblings().first().text();
//alert(sid);
$.ajax({
//几个参数需要注意一下
type: "GET",//方法类型
cache: false,
dataType: "json",//预期服务器返回的数据类型
url: "edit/"+sid ,//url
success: function (data) {
//console.log(data);//打印服务端返回的数据(调试用)
if (data.status == 200) {
var stu = data.data;
$("#sid").val(stu.sno);
$("#sname").val(stu.sname);
if(stu.gender == "男" || stu.gender == "1"){
$("#male").prop("checked",true);
}else{
$("#female").prop("checked",true);
}
//$("#birth").val(stu.birth);
$('.form_date').datetimepicker("setDate", new Date(stu.birth));
$("#filePath").val(stu.photoUrl);
$("#photo2").attr("src",stu.photoUrl);
$('#edit').modal('show');
}
},
error : function() {
alert("异常!");
}
});
}
function save(){
$.ajax({
//几个参数需要注意一下
type: "post",//方法类型
dataType: "json",//预期服务器返回的数据类型
url: "save" ,//url
data: $("#register").serialize(),
success: function (data) {
//console.log(data);//打印服务端返回的数据(调试用)
if (data.status == 200) {
$('#edit').modal('hide');
//$("#edit").css("display","none");
//$("#register")[0].reset();
//$("#photo2").attr("src","images/default.png");
//alert(data.message);
$table.bootstrapTable('refresh');
}
},
error : function() {
alert("异常!");
}
});
}
function upload(){
var file = $("#photo").get(0).files[0];
var formData = new FormData();
formData.append("source",file);
$.ajax({
url:"upload/file",
type:"post",
dataType:"json",
cache:false,
data:formData,
contentType:false,
processData:false,
success:function(data){
if(data.status==200){
$("#photo2").attr("src",data.data);
$("#filePath").val(data.data);
}
console.log("hello test");
}
});
}
function del(sid){
//var sid = $(e).parent().siblings().first().text();
var yesOrNo = confirm("确定要删除该学生么?");
if(yesOrNo){
$.ajax({
//几个参数需要注意一下
type: "DELETE",//方法类型
dataType: "json",//预期服务器返回的数据类型
url: "delete/"+sid ,//url
success: function (data) {
console.log(data.msg);//打印服务端返回的数据(调试用)
if (data.status == 200) {
$table.bootstrapTable('refresh');
}
},
error : function() {
alert("异常!");
}
});
}
}
function exportData(){
//window.open("export" ,"_blank");
var xhr ;
if(window.XMLHttpRequest){//code for IE7+,Firefox,Chrome,Opera,Safari
xhr = new XMLHttpRequest();
}else{//code for IE6,IE5
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
var url = 'export';
xhr.open("post", url, true);
//设置响应类型为blob类型
xhr.responseType = "blob";
xhr.onload = function () {
if (this.status == "200") {
var name = xhr.getResponseHeader("Content-disposition");
var fileName = name.substring(20, name.length);
//获取响应文件流
var blob = this.response;
if (blob && blob.size > 0) {
saveAs(blob, fileName);//处理二进制数据,让浏览器认识它
}
}
}
xhr.send();
}
github项目地址
https://github.com/yangzc23/studentboot
参考资料
[01] springmvc接收日期参数转换
[02] bootstrap-datetimepicker 日期插件设置默认初始值为上一个月
[03] @DateTimeFormat 和 @JsonFormat 注解
[04] Java 日期 解析减少一天问题。神奇
[05] java 关于时间返回结果与参数的注解@DatetimeFormat和@JsonFormat
[06] 在SpringBoot中 日期型转json格式 少8个小时 时区问题
微信扫一扫关注公众号
点击链接加入群聊
https://jq.qq.com/?_wv=1027&k=5eVEhfN
软件测试学习交流QQ群号:511619105
上一篇: spring框架1
下一篇: 【LeetCode】 链表
推荐阅读
-
springboot使用Mybatis(xml和注解)过程全解析
-
使用SpringBoot和SpringSecurity实现 JWT 认证与授权
-
SpringBoot使用注解实现事务管理
-
MySQL安装教程并使用springboot2和Mybatis测试
-
使用Python中的列表和字典实现名片管理操作
-
使用python实现学生信息管理系统
-
集群管理中资源限制和资源分配来实现资源的使用量
-
Asp.Net Core中配置使用Kindeditor富文本编辑器实现图片上传和截图上传及文件管理和上传(开源代码.net core3.0)
-
springBoot+security+mybatis 实现用户权限的数据库动态管理
-
Thymeleaf+SpringBoot+Mybatis实现的家庭财务管理系统