使用SpringBoot+EasyUI实现带图片字段的表的CRUD,包括分页和模糊查询。
1、前端jQuery EasyUI可去中文官网下载最新的http://www.jeasyui.net/download/jquery.html
2、后端SpringBoot+MyBatis本篇只展示其配置文件、配置类和controller层。
<html>
<head>
<meta charset="UTF-8">
<title>学生管理title>
<link rel="stylesheet" type="text/css" href="ui/themes/default/easyui.css">
<link rel="stylesheet" type="text/css" href="ui/themes/icon.css">
<script type="text/javascript" src="ui/jquery.min.js">script>
<script type="text/javascript" src="ui/jquery.easyui.min.js">script>
<script type="text/javascript" src="ui/locale/easyui-lang-zh_CN.js">script>
<script type="text/javascript" src="ui/ajaxfileupload.js">script>
<script type="text/javascript" src="ui/jquery.serializejson.js">script>
<script type="text/javascript" src="./js/crud.js">script>
<script type="text/javascript">
var name = "student";
var width = 350;
var height = 220;
var columns = [[
{
field: 'id', title: '学生编号', width: 100},
{
field: 'image', title: '学生照片', formatter:showImage},
{
field: 'name', title: '学生姓名', width: 100},
{
field: '-', title: '操作', width: 80,
formatter: function (value, row, index) {
var oper = ' + row.id + ')">修改';
oper += ' + row.id + ')">删除';
return oper;
}
}
]];
script>
head>
<body>
<div class="easyui-panel" style="padding-left:4px;border-bottom:0px;">
<div style="height:4px;">div>
<form id="searchForm">
<table>
<tr>
<td>学生姓名td>
<td><input name="name"/>td>
<td>
<button id="searchBtn" type="button">查询button>
td>
tr>
table>
form>
<div style="height:4px;">div>
div>
<table id="grid">table>
<div id="editDlg">
<form id="editForm">
<input type="hidden" name="id"/>
<table>
<tr>
<td width="25%">学生图片td>
<td>
<input type="hidden" value="" name="image" id="pic">
<image id="img" src="" style='width:96px;height:96px'/>
<input class="easyui-filebox" id="fileId" name="file"
data-options="onChange:changeImg" buttonText="请选择一张图片"
/>
td>
tr>
<tr>
<td>学生姓名td>
<td><input name="name">td>
tr>
table>
<button id="saveBtn" type="button">保存button>
form>
div>
body>
html>
ajaxfileupload.js和jquery.serializejson.js可自取
链接:https://pan.baidu.com/s/1SJz0f_zwo8zqs5VSBNBD6w 提取码:mt62
crud.js
var method = ""; // 确定提交的方法是新增还是保存
$(function () {
$('#grid').datagrid({
url: name + '/findPage', // 从远程站点请求数据的URL
columns: columns, // 数据网格(datagrid)的列(column)的配置对象,更多细节请参见列(column)属性
height: $(window).height() - 60, // 设置整体网格高度
width: $(window).width() - 30, // 设置整体网格宽度
singleSelect: true, //设置为 true,则只允许选中一行。
pagination: true, //设置为 true,则在数据网格(datagrid)底部显示分页工具栏
toolbar: [
{
text: '新增',
iconCls: 'icon-add',
handler: function () {
// 指定保存事件提交的方法
method = "/add";
$('#editForm').form('clear'); // 清空表格
$('#img').attr("src", ""); // 清空图片
// 弹出窗口
$('#editDlg').dialog('open');
}
}
]
});
// 启动分页工具栏中的刷新按钮
$('#grid').pagination({
showRefresh: true
});
// 查询
$('#searchBtn').bind('click', function () {
// 把表单数据转换成JSON对象
var formData = $('#searchForm').serializeJSON();
$('#grid').datagrid('load', formData);
});
var h = 200;
var w = 300;
if (typeof (height) != "undefined") {
h = height;
}
if (typeof (width) != "undefined") {
w = width;
}
// 编辑窗口
$('#editDlg').dialog({
title: '编辑窗口', //对话框的标题文本。
width: w, //设置面板(panel)的宽度。
height: h, //设置面板(panel)的高度。
closed: true, // 刚开始窗口是否为关闭状态,true表示关闭
modal: true // 模式窗口,背景窗口变灰色,不可选
});
// 保存动作
$('#saveBtn').bind('click', function () {
var formData = $('#editForm').serializeJSON();
$.ajax({
url: name + method,
data: formData,
dataType: 'json',
type: 'post',
success: function (rtn) {
$.messager.alert('提示', rtn.msg, 'info', function () {
if (rtn.success) {
// 成功的话,关闭窗口
$('#editDlg').dialog('close');
// 刷新表格数据
$('#grid').datagrid('reload'); //重新加载行,就像 load 方法一样,但是保持在当前页。
}
});
}
});
});
});
// 删除
function del(id) {
$.messager.confirm('确认', '确认要删除吗?', function (yes) {
if (yes) {
// 删除动作
$.ajax({
url: name + '/delete?id=' + id,
dataType: 'json',
type: 'post',
success: function (rtn) {
$.messager.alert('提示', rtn.msg, 'info', function () {
if (rtn.success) {
// 刷新表格数据
$('#grid').datagrid('reload');
}
});
}
});
}
});
}
// 修改
function edit(id) {
// 弹出窗口
$('#editDlg').dialog('open');
// 清空表单内容
$('#editForm').form('clear');
// 加载数据,用于修改前读取记录信息
$.ajax({
url: name + '/findOne?id=' + id,
dataType: 'json',
type: 'post',
success: function (rtn) {
$('#editForm').form('load', rtn);
if (name == "student") {
$('#img').attr("src", rtn.image);
}
}
});
method = "/update";
}
// 图片展示
function showImage(value, row, index) {
if (value) {
return "
";
}
}
// 异步上传图片
function changeImg() {
// 清空时再次触发此方法,直接返回
if ($('#fileId').filebox('getValue') == "") {
return;
}
// 异步上传
$.ajaxFileUpload({
url: 'upload/uploadFile',
dataType: 'json',
type: 'post',
secureuri: false,
fileElementId: 'filebox_file_id_1', // 单张图片,固定写法
success: function (data) {
$('#img').attr("src", data.msg); // 图片回显赋值
$('#pic').attr("value", data.msg); // 提交的数据赋值
}
});
//上传成功后清空里面的值
$('#fileId').filebox('clear');
}
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>
<groupId>com.wdp.wwwgroupId>
<artifactId>springboot-easyui-200606artifactId>
<version>1.0.0-SNAPSHOTversion>
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>2.0.6.RELEASEversion>
parent>
<properties>
<project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8project.reporting.outputEncoding>
<java.version>1.8java.version>
properties>
<dependencies>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-jdbcartifactId>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
dependency>
<dependency>
<groupId>org.mybatis.spring.bootgroupId>
<artifactId>mybatis-spring-boot-starterartifactId>
<version>1.3.2version>
dependency>
<dependency>
<groupId>tk.mybatisgroupId>
<artifactId>mapper-spring-boot-starterartifactId>
<version>2.0.2version>
dependency>
<dependency>
<groupId>com.github.pagehelpergroupId>
<artifactId>pagehelper-spring-boot-starterartifactId>
<version>1.2.3version>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
plugin>
plugins>
build>
project>
# 映射端口
server.port=8001
# 上传图片存放地址
file-save-path=D:/ref/pic/images/
# 设置上传文件大小 如果是想要不限制文件上传的大小,那么就把两个值都设置为-1
# 设置单个文件的大小
spring.servlet.multipart.max-file-size=1MB
# 设置单次请求的文件的总大小
spring.servlet.multipart.max-request-size=5MB
#打印sql,方便调试
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
# 设置数据源 驱动SpringBoot自己可以推测
spring.datasource.url=jdbc:mysql:///db1
spring.datasource.username=root
spring.datasource.password=root
# 别名扫描
mybatis.type-aliases-package=com.wdp.www.pojo
# mapper.xml配置文件扫描,如果有可放开下面的注释
# mybatis.mapper-locations=classpath:mybatis/mappers/*.xml
Result.java
package com.wdp.www.util;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import java.io.Serializable;
/**
* 返回信息实体
*
* @author Dongpo
*/
@Getter
@Setter
@AllArgsConstructor
public class Result implements Serializable {
/**
* 是否成功
*/
private boolean success;
/**
* 提示信息
*/
private String msg;
}
PageResult.java
package com.wdp.www.util;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import java.io.Serializable;
import java.util.List;
/**
* 分页结果
*
* @author Dongpo
*/
@Getter
@Setter
@AllArgsConstructor
public class PageResult implements Serializable {
/**
* 总记录数
*/
private Long total;
/**
* 当前页结果
*/
private List rows;
}
StudentController.java
package com.wdp.www.controller;
import com.wdp.www.pojo.Student;
import com.wdp.www.service.StudentService;
import com.wdp.www.util.PageResult;
import com.wdp.www.util.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @Description 学生
* @Author DongPo
*/
@RestController
@RequestMapping("student")
public class StudentController {
@Autowired
private StudentService studentService;
@RequestMapping("findPage")
public PageResult findPage(Student student, Integer page, Integer rows) {
PageResult pageResult = studentService.findPage(student, page, rows);
return pageResult;
}
@RequestMapping("findOne")
public Student findOne(Long id) {
Student student = studentService.findOne(id);
return student;
}
@RequestMapping("add")
public Result add(Student student) {
try {
studentService.add(student);
return new Result(true, "添加成功");
} catch (Exception e) {
e.printStackTrace();
return new Result(false, "添加失败");
}
}
@RequestMapping("update")
public Result update(Student student) {
try {
studentService.update(student);
return new Result(true, "修改成功");
} catch (Exception e) {
e.printStackTrace();
return new Result(false, "修改失败");
}
}
@RequestMapping("delete")
public Result delete(Long id) {
try {
studentService.delete(id);
return new Result(true, "删除成功");
} catch (Exception e) {
e.printStackTrace();
return new Result(false, "删除失败");
}
}
}
UploadController.java
package com.wdp.www.controller;
import com.wdp.www.util.Result;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;
/**
* @Description 上传图片
* @Author DongPo
*/
@Controller
@RequestMapping("upload")
public class UploadController {
/**
* 时间格式化,用来创建文件夹
*/
private static final SimpleDateFormat SDF = new SimpleDateFormat("yyyy/MM/dd/");
/**
* 设置最大文件限制 单位bit
*/
private static final int FILE_MAX_SIZE = 1 * 1024 * 1024;
/**
* 文件类型限制
*/
private static final List<String> FILE_CONTENT_TYPES = new ArrayList<>();
static {
FILE_CONTENT_TYPES.add("image/jpeg");
FILE_CONTENT_TYPES.add("image/jpg");
FILE_CONTENT_TYPES.add("image/png");
}
/**
* 图片保存路径,自动从properties文件中获取数据
* 示例:D:/ref/pic/images/
*/
@Value("${file-save-path}")
private String fileSavePath;
@RequestMapping("uploadFile")
@ResponseBody
public Result uploadFile(@RequestParam("file") MultipartFile file, HttpServletRequest request) {
// 0.文件检查
// 检查大小
long size = file.getSize();
if (size > FILE_MAX_SIZE) {
return new Result(false, "文件大小不能超过" + (FILE_MAX_SIZE / 1024) + "KB");
}
// 检查类型
String contentType = file.getContentType();
if (!FILE_CONTENT_TYPES.contains(contentType)) {
return new Result(false, "只支持以下类型的文件格式:" + FILE_CONTENT_TYPES);
}
// 1.后半段目录:2020/06/07/
String directory = SDF.format(new Date());
/**
* 2.文件保存目录 D:/ref/pic/images/2020/06/17/
* 如果目录不存在,则创建
*/
File dir = new File(fileSavePath + directory);
if (!dir.exists()) {
dir.mkdirs();
}
System.out.println("图片上传,保存位置:" + fileSavePath + directory);
// 3.给文件重新设置一个名字
// 截取后缀
String suffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
String newFileName = UUID.randomUUID().toString().replaceAll("-", "") + suffix;
// 4.创建这个新文件
File newFile = new File(fileSavePath + directory + newFileName);
// 5.复制操作
try {
file.transferTo(newFile);
// 协议 :// ip地址 :端口号 / 文件目录(/images/2020/06/07/xxx.jpg)
String url = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + "/images/" + directory + newFileName;
System.out.println("图片上传,访问URL:" + url);
return new Result(true, url);
} catch (IOException e) {
return new Result(false, "上传异常");
}
}
}
FileConfig.java
package com.wdp.www.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* @Description 映射路径配置
* @Author DongPo
*/
@Configuration
public class FileConfig implements WebMvcConfigurer {
/**
* 图片保存路径,自动从properties文件中获取数据
* 示例:D:/ref/pic/images/
*/
@Value("${file-save-path}")
private String fileSavePath;
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
/**
* 配置资源映射
* 意思是:如果访问的资源路径是以“/images/”开头的,
* 就给我映射到本机的“D:/ref/pic/images/”这个文件夹内,去找你要的资源
* 注意:D:/ref/pic/images/ 后面的 “/”一定要带上
*/
registry.addResourceHandler("/images/**")
.addResourceLocations("file:" + fileSavePath);
}
}
创造工具的人是伟大的,所以对他们最好的感谢就是合理的使用这些工具。
前端为jQuery EasyUI的简单使用,实体类使用了lombok插件,Mapper接口使用了通用Mapper,业务中使用了分页工具,web层为SpringBoot的简单使用。
总体来说,这是一种简便的、易于上手的从前端到后端的全栈解决方案。
牛顿说过,如果说我能够看的远一些,那是因为我站在巨人的肩膀上。
参考1:https://blog.csdn.net/sd6275832ght
参考2:https://blog.csdn.net/RuanBigShuai