【SpringBoot】18 上传文件到数据库(Thymeleaf + MySQL)
Git仓库
https://gitee.com/Lin_DH/system
介绍
使用 Thymeleaf 写的页面,将(txt、jpg、png)格式文件上传到 MySQL 数据库中。
依赖
pom.xml
<!-- https://mvnrepository.com/artifact/com.mysql/mysql-connector-j --><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><version>8.0.33</version></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.7</version></dependency>
数据库配置
application.yml
spring:jackson:date-format: yyyy-MM-dd HH:mm:sstime-zone: GMT+8datasource:driver-class-name: com.mysql.jdbc.Driverurl: jdbc:mysql://localhost:3306/system?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8username: rootpassword: rootmybatis-plus:type-aliases-package: com.lm.system.commonmapper-locations: classpath:com.lm.system/mapper/*Mapper.xmlcheck-config-location: trueconfiguration:#日志实现,不配置不会输出SQL日志log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
SQL
t_file.sql
/*Navicat Premium Data TransferSource Server : localhostSource Server Type : MySQLSource Server Version : 50734Source Host : localhost:3306Source Schema : systemTarget Server Type : MySQLTarget Server Version : 50734File Encoding : 65001Date: 18/10/2024 15:14:51
*/SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;-- ----------------------------
-- Table structure for t_file
-- ----------------------------
DROP TABLE IF EXISTS `t_file`;
CREATE TABLE `t_file` (`id` int(11) NOT NULL AUTO_INCREMENT,`name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,`format` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,`data` longblob NOT NULL,`size` double NOT NULL,`create_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) ON UPDATE CURRENT_TIMESTAMP(0),PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;SET FOREIGN_KEY_CHECKS = 1;
实现代码
第一步:编写上传页面
uploadToBD.html
<!DOCTYPE html>
<html lang="en">
<head lang="en"><meta charset="UTF-8" /><title>文件上传到数据库页面</title>
</head>
<body>
<h1>文件上传到数据库页面</h1>
<form method="post" action="/uploadToDB" enctype="multipart/form-data">请选择要上传的txt/jpeg/png格式文件:<input type="file" name="file"><br><hr><input type="submit" value="提交">
</form>
</body>
</html>
第二步:编写文件实体类
SysFile.java
package com.lm.system.common;import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;import java.util.Date;/*** @author DUHAOLIN* @date 2024/10/17*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class SysFile {@TableId(value = "id", type = IdType.INPUT)private Integer id;private String name;private String format;private byte[] data;private long size;private Date createTime;}
第三步:编写dao层接口
SysFileMapper.java
package com.lm.system.mapper;import com.baomidou.dynamic.datasource.annotation.DS;
import com.lm.system.common.SysFile;/*** @author DUHAOLIN* @date 2024/10/17*/
//@DS("system")
public interface SysFileMapper {int insertFile(SysFile file);}
第四步:编写dao层SQL
SysFileMapper.xml
<?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.lm.system.mapper.SysFileMapper"><resultMap id="beans" type="com.lm.system.common.SysFile"><id property="id" column="id" jdbcType="INTEGER" /><result property="name" column="name" jdbcType="VARCHAR" /><result property="format" column="format" jdbcType="VARCHAR" /><result property="data" column="data" jdbcType="BLOB" /><result property="size" column="size" jdbcType="DOUBLE" /> <result property="createTime" column="create_time" jdbcType="TIMESTAMP" /></resultMap><insert id="insertFile" parameterType="com.lm.system.common.SysFile">INSERT INTO t_file (NAME, FORMAT, DATA, SIZE)VALUES (#{name}, #{format}, #{data}, #{size})</insert></mapper>
第五步:添加 controller
FileController.java
import com.lm.system.exception.FileException;
import com.lm.system.mapper.SysFileMapper;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;import javax.annotation.Resource;
import java.io.IOException;
import java.nio.file.Files;
import java.util.Arrays;
import java.util.List;/*** @author DUHAOLIN* @date 2024/10/15*/
@Controller
public class FileController {@Resourceprivate SysFileMapper fileMapper;private final static String FILE_FORMAT_TXT = "txt";private final static String FILE_FORMAT_JPEG = "jpg";private final static String FILE_FORMAT_PNG = "png";@Value("${file.upload.path}")private String path;private void checkFile(MultipartFile file, String[] fileFormats) {//校验文件大小checkSize(file.getSize());//校验文件名checkFilename(file.getOriginalFilename());//校验文件格式checkFileFormat(file.getOriginalFilename(), fileFormats);}private void checkSize(long size) {if (size > 10485760L) //10MBthrow new FileException("文件大于10MB");}private void checkFilename(String filename) {if (!StringUtils.hasText(filename))throw new FileException("文件名有误");}private void checkFileFormat(String filename, String[] fileFormats) {int i = filename.lastIndexOf(".");String suffix = filename.substring(i + 1); //文件后缀long c = Arrays.stream(fileFormats).filter(s -> s.equals(suffix)).count(); //判断是否存在该文件后缀if (c < 1) throw new FileException("文件格式有误,该文件类型为:" + suffix);}@GetMapping("uploadToDBPage")public String uploadToDBPage() {return "uploadToDB";}@PostMapping("uploadToDB")@ResponseBodypublic String uploadToDB(@RequestParam("file") MultipartFile file) throws IOException {//校验文件try {String[] fileFormats = { FILE_FORMAT_TXT, FILE_FORMAT_JPEG, FILE_FORMAT_PNG };checkFile(file, fileFormats);} catch (FileException e) {e.printStackTrace();return e.getMessage();}//构建存储对象SysFile sysFile = SysFile.builder().name(getFilename(file.getOriginalFilename())).format(getFileFormat(file.getOriginalFilename())).data(file.getBytes()).size(file.getSize()).build();int i = fileMapper.insertFile(sysFile);return i > 0 ? "添加成功" : "添加失败";}private String getFileFormat(String filename) {int i = filename.lastIndexOf(".");return filename.substring(i + 1); //文件后缀}/*** 获取不带后缀的文件名*/private String getFilename(String originalFilename) {int i = originalFilename.lastIndexOf(".");return originalFilename.substring(0, i);}}
第六步:配置默认 tomcat 最大吞吐量
application.yml
server:port: 8888 tomcat:max-swallow-size: 100MB #tomcat的最大吞吐量,默认为2MB,-1则为不限制spring:application:name: systemservlet:multipart:max-file-size: 10MB #默认为1MB max-request-size: 10MB #默认为10MB
上传大于配置文件设定的文件后,页面无响应。
添加上 tomcat 最大吞吐量配置,则能够正常返回。
存在全局异常捕获的可以把文件最大文件限制异常捕获的也加上。
GlobalExceptionHandler.java
@Value("${spring.servlet.multipart.max-file-size}")private String maxFileSize;@ResponseStatus(HttpStatus.BAD_REQUEST)@ExceptionHandler({MaxUploadSizeExceededException.class})public String handleMaxUploadSizeException(Exception e, HttpServletRequest request) {log.error("400-上传文件超过最大限制{},{},{}", maxFileSize, e.getMessage(), request.getServletPath());e.printStackTrace();return ResultBody.build(HttpStatus.BAD_REQUEST).setMsg("上传文件超过最大限制" + maxFileSize).getReturn();}
效果图
txt
上传 txt 格式文件,添加成功。
jpg
上传 jpg 格式文件,添加成功。
png
上传 png 格式文件,添加成功。
csv
上传允许格式之外的格式文件,如 csv 文件,则页面返回“文件格式有误”,上传失败。
项目结构图
相关文章:

【SpringBoot】18 上传文件到数据库(Thymeleaf + MySQL)
Git仓库 https://gitee.com/Lin_DH/system 介绍 使用 Thymeleaf 写的页面,将(txt、jpg、png)格式文件上传到 MySQL 数据库中。 依赖 pom.xml <!-- https://mvnrepository.com/artifact/com.mysql/mysql-connector-j --><depende…...
计算机体系结构之系统吞吐量(三)
前面章节《计算机体系结构之多级缓存、缓存miss及缓存hit(二)》讲了关于系统多级缓存的相关内容,其中提及了系统吞吐量一词。在此章将对其进行讲解。 系统吞吐量是计算机体系结构的一个重要指标,其衡量的是系统在单位时间内处理工…...

高级 HarmonyOS主题课—— 帮助快速构建各种文本识别应用的课后习题
天地不仁,以万物为刍狗; 圣人不仁,以百姓为刍狗。 天地之间,其犹橐龠乎? 虚而不屈,动而俞出。 多闻数穷,不若守于中。 本文内容主要来自 <HarmonyOS主题课>帮助快速构建各种文本识别应用 …...
windows C#-异常和异常处理概述
C# 语言的异常处理功能有助于处理在程序运行期间发生的任何意外或异常情况。 异常处理功能使用 try、catch 和 finally 关键字来尝试执行可能失败的操作、在你确定合理的情况下处理故障,以及在事后清除资源。 公共语言运行时 (CLR)、.NET/第三方库或应用程序代码都可…...
每日一题——第一百二十四题
题目:进制转换 #pragma once#include<stdio.h> #include<ctype.h> #include<string.h>/// <summary> /// //将字符串表示的任意进制数转为十进制 /// </summary> /// <param name"str">字符串</param> /// &l…...
在 CentOS 7 上设置 OpenResty 开机启动
在 CentOS 7 上设置 OpenResty 开机启动,可以按照以下步骤进行操作: 创建 Systemd 服务文件: 首先,您需要为 OpenResty 创建一个 Systemd 服务文件。使用文本编辑器(如 vi 或 nano)创建一个新的服务文件。 …...

势不可挡 创新引领 | 生信科技SOLIDWORKS 2025新品发布会·苏州站精彩回顾
2024年11月01日,由生信科技举办的SOLIDWORKS 2025新产品发布会在江苏苏州圆满落幕。现场邀请到制造业的专家学者们一同感受SOLIDWORKS 2025最新功能,探索制造业数字化转型之路。 在苏州站活动开场,达索系统专业客户事业部华东区渠道经理马腾飞…...
数仓之全量表、增量表、快照表、切片表、拉链表的基本概念
文章摘自:数仓之全量表、增量表、快照表、切片表、拉链表-腾讯云开发者社区-腾讯云 一、全量表 记录每天所有最新状态的数据,有无变化都要上报,每次往全量表里面写数据都会覆盖之前的数据 缺点:不能记录数据的历史变化ÿ…...
【富集分析GSEA】如何理解富集分析以及应用
如何理解富集分析 富集分析不同的方式 富集分析 不同的方式 直接使用疾病特征进行富集分析(不翻转上调和下调的基因) 目的:如果你的目标是了解疾病状态的生物学特征和功能路径,那么应该直接使用疾病特征(包含疾病状态…...
一七五、HTML 不同类型的事件及其说明和示例
HTML 事件处理程序是通过 JavaScript 来捕获和响应不同的用户操作、系统事件或浏览器事件。下面是不同类型的事件及其说明和示例。 Window 事件 1. onresize 当浏览器窗口的大小发生变化时触发。 <!DOCTYPE html> <html lang"en"> <head><m…...

数量少的连锁店要不要用智能巡检?
无论是在新闻报道中,还是企业定制目标客户时,人们都更喜欢聚焦原本就已经站在各行业金字塔尖的那 1%,剩下的 99% 却常常被忽略。 比如此刻我正在搜索中小型连锁企业智能巡检相关的资讯,但网页展示的结果基本围绕着「中大型、1000门…...
【CSS】外边距塌陷
问题背景 在移动应用页面开发中,父元素和子元素外边距合并,导致布局效果和预期不一致。 <template><view class"container"><view class"card"><p>TEST</p></view></view> </templa…...
WPF MVVM入门系列教程(二、依赖属性)
说明:本文是介绍WPF中的依赖属性功能,如果对依赖属性已经有了解了,可以浏览后面的文章。 为什么要介绍依赖属性 在WPF的数据绑定中,密不可分的就是依赖属性。而MVVM又是跟数据绑定紧密相连的,所以在学习MVVM之前&…...
Springboot集成syslog+logstash收集日志到ES
Springboot集成sysloglogstash收集日志到ES 1、背景 Logstash 是一个实时数据收集引擎,可收集各类型数据并对其进行分析,过滤和归纳。按照自己条件分析过滤出符合的数据,导入到可视化界面。它可以实现多样化的数据源数据全量或增量传输&…...

Devops业务价值流:软件研发最佳实践
在当今快速迭代的软件开发环境中,DevOps业务价值流已成为推动软件研发高效与质量并重的关键实践。软件研发阶段作为产品生命周期的核心环节,其每一步都承载着将创意转化为现实的重要使命。在历经需求澄清的精准定位、架构设计的宏观规划以及项目初始化的…...
Matplotlib 绘图艺术:从新手到高手的全面指南
引言 在数据科学和机器学习领域,数据可视化是一项至关重要的技能。一个优秀的可视化图表可以直观地展示数据的内在规律,帮助我们更好地理解数据,并做出更明智的决策。而在众多的绘图库中,Matplotlib 是 Python 中最强大、最灵活的…...

[ shell 脚本实战篇 ] 编写恶意程序实现需求(恶意程序A监测特定目录B出现特定文件C执行恶意操作D-windows)
🍬 博主介绍 👨🎓 博主介绍:大家好,我是 _PowerShell ,很高兴认识大家~ ✨主攻领域:【渗透领域】【数据通信】 【通讯安全】 【web安全】【面试分析】 🎉点赞➕评论➕收藏 养成习…...

SQLI LABS | Less-33 GET-Bypass AddSlashes()
关注这个靶场的其它相关笔记:SQLI LABS —— 靶场笔记合集-CSDN博客 0x01:过关流程 输入下面的链接进入靶场(如果你的地址和我不一样,按照你本地的环境来): http://localhost/sqli-labs/Less-33/ "Ad…...

界面控件DevExpress WPF中文教程:Data Grid——卡片视图设置
DevExpress WPF拥有120个控件和库,将帮助您交付满足甚至超出企业需求的高性能业务应用程序。通过DevExpress WPF能创建有着强大互动功能的XAML基础应用程序,这些应用程序专注于当代客户的需求和构建未来新一代支持触摸的解决方案。 无论是Office办公软件…...

flink 内存配置(一):设置Flink进程内存
flink 内存配置(一):设置Flink进程内存 flink 内存配置(二):设置TaskManager内存 flink 内存配置(三):设置JobManager内存 flink 内存配置(四)…...

【Python】 -- 趣味代码 - 小恐龙游戏
文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...

基于FPGA的PID算法学习———实现PID比例控制算法
基于FPGA的PID算法学习 前言一、PID算法分析二、PID仿真分析1. PID代码2.PI代码3.P代码4.顶层5.测试文件6.仿真波形 总结 前言 学习内容:参考网站: PID算法控制 PID即:Proportional(比例)、Integral(积分&…...
React hook之useRef
React useRef 详解 useRef 是 React 提供的一个 Hook,用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途,下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...

解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八
现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet,点击确认后如下提示 最终上报fail 解决方法 内核升级导致,需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...

高频面试之3Zookeeper
高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个?3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制(过半机制࿰…...

【机器视觉】单目测距——运动结构恢复
ps:图是随便找的,为了凑个封面 前言 在前面对光流法进行进一步改进,希望将2D光流推广至3D场景流时,发现2D转3D过程中存在尺度歧义问题,需要补全摄像头拍摄图像中缺失的深度信息,否则解空间不收敛…...

SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现
摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序,以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务,提供稳定高效的数据处理与业务逻辑支持;利用 uniapp 实现跨平台前…...
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别 直接训练提示词嵌入向量的核心区别 您提到的代码: prompt_embedding = initial_embedding.clone().requires_grad_(True) optimizer = torch.optim.Adam([prompt_embedding...
Android Bitmap治理全解析:从加载优化到泄漏防控的全生命周期管理
引言 Bitmap(位图)是Android应用内存占用的“头号杀手”。一张1080P(1920x1080)的图片以ARGB_8888格式加载时,内存占用高达8MB(192010804字节)。据统计,超过60%的应用OOM崩溃与Bitm…...

OPenCV CUDA模块图像处理-----对图像执行 均值漂移滤波(Mean Shift Filtering)函数meanShiftFiltering()
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 在 GPU 上对图像执行 均值漂移滤波(Mean Shift Filtering),用于图像分割或平滑处理。 该函数将输入图像中的…...