如何使用 MySQL、Thymeleaf 和 Spring Boot 从数据库上传和下载多个文件

使用百里香叶的春季启动上传和下载示例。在本文中,我们将学习如何从数据库上传和下载文件。

上传和下载文件是任何应用程序的重要组成部分之一。众所周知,我们使用 Spring Boot 使开发过程变得简单。因此,在这里我们将创建一个示例来从数据库上传和下载文件。我们将在视图层使用百里香叶模板。Spring Data JPA 将在数据访问层使用。这里的关系数据库是MYSQL。

使用百里香叶的春季启动上传和下载文件示例

在此示例中,我们将创建一个视图,在其中查看如何上传和下载文件。

第 1 步:打开 IDE STS-弹簧工具套件

第 2 步:转到 Spring 入门项目>文件。

步骤3: 现在,填写如下所示的所有字段,然后单击下一步。

步骤4: 现在,添加百里香叶,春季数据JPA,龙目岛和春季网络的依赖项,然后单击下一步>完成。

现在,等待一段时间,您的项目结构将准备就绪。转到pom.xml文件,您将看到将自动添加以下依赖项

<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.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.6</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>upload.download</groupId>
    <artifactId>springboot-thymeleaf-mysql-upload-download-files</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>springboot-thymeleaf-mysql-upload-download-files</name>
    <url>http://localhost:8080</url>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>javax.xml.bind</groupId>
            <artifactId>jaxb-api</artifactId>
            <version>2.4.0-b180830.0359</version>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

在 MYSQL 中创建数据库

mysql> create database updownload;

配置应用程序。属性文件

spring.jpa.hibernate.ddl-auto=update
spring.datasource.url=jdbc:mysql://localhost:3306/updownload?autoReconnect=true&useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
spring.datasource.username=root
spring.datasource.password=root

#Multipart
spring.servlet.multipart.enabled=true
spring.servlet.multipart.file-size-threshold=2KB
spring.servlet.multipart.max-file-size=200MB
spring.servlet.multipart.max-request-size=215MB
  • spring.jpa.hibernate.ddl-auto设置为更新,以便我们将要进行的任何更改都将反映在架构中。
  • spring.datasource.url 用于设置 MYSQL DB 的 URL
  • spring.datasource.username 用于设置 username 和 spring。 datasource. password用于设置密码。
  • spring.datasource.driver-class-name 用于设置驱动程序类名。
  • spring.jpa.show-sql 设置为 true 以显示 Hibernate 生成的 SQL。
  • spring.jpa.properties.hibernate.dialect 用于为所选数据库生成更好的 SQL。
  • spring.jpa.properties.hibernate.format_sql设置为 true 以格式化 SQL 查询。
  • server.port 设置为 8888
  • spring.servlet.multipart.enabled 设置为 true 以提供对 multipart 的支持。
  • spring.servlet.multipart.file-size-threshold用于设置文件的最大大小。在阈值大小之后,文件将被写入光盘。
  • spring.servlet.multipart.max-file-size 表示最大文件大小
  • spring.servlet.multipart.max-request-size 表示总请求大小。

创建模型类

FileEntity .java

package upload.download.entity;

import javax.persistence.*;

@Entity
@Table(name = "file_table")
public class FileEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "file_id")
    private Long fileId;

    @Column(name = "file_name")
    private String fileName;

    @Column(name = "file_type")
    private String fileType;
    @Lob
    @Column(name = "file_byte")
    private byte[] fileByte;

    public FileEntity() {
    }

    public FileEntity(String fileName, String fileType, byte[] fileByte) {
        this.fileName = fileName;
        this.fileType = fileType;
        this.fileByte = fileByte;
    }

    public Long getId() {
        return fileId;
    }

    public void setId(Long id) {
        this.fileId = id;
    }

    public String getFileName() {
        return fileName;
    }

    public void setFileName(String fileName) {
        this.fileName = fileName;
    }

    public String getFileType() {
        return fileType;
    }

    public void setFileType(String fileType) {
        this.fileType = fileType;
    }

    public byte[] getFileByte() {
        return fileByte;
    }

    public void setFileByte(byte[] fileByte) {
        this.fileByte = fileByte;
    }
}

FileInfo.java

package upload.download.entity;

public class FileInfo {

    private String fileInfoName;
    private String fileURL;

    public FileInfo() {
    }

    public FileInfo(String fileInfoName, String fileURL) {
        this.fileInfoName = fileInfoName;
        this.fileURL = fileURL;
    }

    public String getFileInfoName() {
        return fileInfoName;
    }

    public void setFileInfoName(String fileInfoName) {
        this.fileInfoName = fileInfoName;
    }

    public String getFileURL() {
        return fileURL;
    }

    public void setFileURL(String fileURL) {
        this.fileURL = fileURL;
    }
}

在数据库中,它将像这样显示

 

现在,使用 MYSQL 工作台将 TinyBLOB 数据类型更改为LongBlob。

创建存储库接口

这里的存储库是 DAO 层,它执行所有数据库操作。创建 FileEntityRepository 接口,该接口将扩展 JPARepository<ClassName, ID>。

package upload.download.repository;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.stereotype.Repository;
import upload.download.entity.FileEntity;

@Repository
@EnableJpaRepositories
public interface FileEntityRepository extends JpaRepository<FileEntity, Long> {
    FileEntity findByFileName(String fileName);
}

创建控制器类

对网页的请求将由控制器类中的处理程序方法使用 @GetMapping 处理。

package upload.download.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import upload.download.entity.FileEntity;
import upload.download.repository.FileEntityRepository;

import java.util.ArrayList;
import java.util.List;

@Controller
public class UploadController {

    @Autowired
    private FileEntityRepository fileEntityRepository;


    /**
     * Get index page
     *
     * @return index
     */

    @GetMapping("/")
    public String getIndexFilePage() {
        return "index";
    }

    @PostMapping("/")
    public String uploadFiles(@RequestParam("files") MultipartFile[] multipartFiles, Model model) {
        List<String> listFileNames = new ArrayList<>();

        try {
            List<FileEntity> storeFiles = new ArrayList<>();

            for (MultipartFile file : multipartFiles) {
                FileEntity fileEntity = fileEntityRepository.findByFileName(file.getOriginalFilename());

                if (fileEntity != null) {
                    fileEntity.setFileByte(file.getBytes());
                } else {
                    fileEntity = new FileEntity(file.getOriginalFilename(), file.getContentType(), file.getBytes());
                }
                listFileNames.add(file.getOriginalFilename());
                storeFiles.add(fileEntity);
            }

            // save all files
            fileEntityRepository.saveAll(storeFiles);

            // successfully message after uploaded
            model.addAttribute("message", "Files uploaded successfully!");
            model.addAttribute("files", listFileNames);
        } catch (Exception e) {
            // fail message for unsupported file or max size
            model.addAttribute("message", "Fail");
            model.addAttribute("files", listFileNames);
        }
        return "index";
    }
}
package upload.download.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.servlet.mvc.method.annotation.MvcUriComponentsBuilder;
import upload.download.entity.FileEntity;
import upload.download.entity.FileInfo;
import upload.download.repository.FileEntityRepository;

import java.util.List;
import java.util.stream.Collectors;

@Controller
public class DownloadController {

    @Autowired
    private FileEntityRepository fileEntityRepository;

    /**
     * Get and display file stored in the database.
     *
     * @return download-file page
     */

    @GetMapping("/download/files")
    public String getListOfFiles(Model model) {
        List<FileInfo> fileInfoList = fileEntityRepository.findAll()
                .stream()
                .map(fileEntity -> {
                            String fileInfoName = fileEntity.getFileName();
                            String fileURL = MvcUriComponentsBuilder
                                    .fromMethodName(
                                            DownloadController.class,
                                            "downloadFile",
                                            fileEntity.getFileName())
                                    .build()
                                    .toString();
                            return new FileInfo(fileInfoName, fileURL);
                        }
                ).collect(Collectors.toList());


        model.addAttribute("files", fileInfoList);
        return "download-file";
    }

    /**
     * Get file to download.
     *
     * @return file from database to be downloaded
     */

    @GetMapping("/download/files/{fileInfoName}")
    public ResponseEntity<byte[]> downloadFile(@PathVariable String fileInfoName) {
        FileEntity downloadFileEntity = fileEntityRepository.findByFileName(fileInfoName);
        return ResponseEntity.ok()
                .header(HttpHeaders.CONTENT_DISPOSITION,
                        "attachment; filename=\"" + downloadFileEntity.getFileName() + "\"")
                .body(downloadFileEntity.getFileByte());
    }
}

@Controller注释将学生控制器类标记为请求处理程序。现在让我们打破上面的代码并理解它。

使用百里香叶创建视图

转到 src/main/resources/template 文件夹并创建一个 index.html 文件。现在在寄存器中.html文件确保添加以下代码:

要了解如何迭代百里香叶中的对象列表,请查看这篇文章 使用 Spring 引导在百里香叶中迭代列表

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Spring Boot - Thymeleaf - MySQL| Upload -- Download -- Files</title>
    <link rel="stylesheet" type="text/css" href="/css/style.css">
</head>
<body>
<div id="wrapper">
    <div id="navigator">
        <!-- Navigator -->
        <nav>
            <div class="navbar">
                <div class="navbar-banner"><a class="white" href="/"><img src="" alt="Logo"></a></div>
                <div class="nav-links"></div>
            </div>
        </nav>
    </div>
    <div class="upload-download-card">
        <h2 style="text-align: center">Spring Thymeleaf MySQL |
            <a class="button-style-1" href="/">Upload</a>
            <a class="button-style-1" href="/download/files">Download</a>
        </h2>
        <hr style="width: 90%; height: 2px; background-color: black;">
        <div>
            <form method="POST" enctype="multipart/form-data" id="fileUploadForm">
                <h3 style="text-align: center">Upload One Or Multiple Files</h3>
                <div id="upload-group">
                    <label for="files">Upload Files:</label>
                    <input type="file" id="files" placeholder="Upload Multiple Files" name="files" multiple>
                    <button type="submit" class="button-style-1" id="btnSubmit">Upload</button>
                </div>
            </form>
            <div>
                <!-- Message Success|Fail-->
                <div class="message-card" th:if="${message}">
                    <strong><span th:text="${message}"/></strong>
                    <hr>
                    <ul th:each="filename: ${files}">
                        <li><span th:text="${filename}"/></li>
                    </ul>
                </div>
            </div>
        </div>
    </div>
</div>
<footer id="footer">
    <div id="footer-content">
        <p>Copyright ©2022 All rights reserved |</p>
        <p title="Popa Catalin">&nbsp;Popa Catalin</p>
    </div>
</footer>
</body>
</html>
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Spring Boot - Thymeleaf - MySQL| Upload -- Download -- Files</title>
    <link rel="stylesheet" type="text/css" href="/css/style.css">
    <link rel="stylesheet" type="text/css" href="/css/table.css">
</head>
<body>
<div id="wrapper">
    <div id="navigator">
        <!-- Navigator -->
        <nav>
            <div class="navbar">
                <div class="navbar-banner"><a class="white" href="/"><img src="" alt="Logo"></a></div>
                <div class="nav-links"></div>
            </div>
        </nav>
    </div>
    <div class="upload-download-card">
        <h2 style="text-align: center">Spring Thymeleaf MySQL |
            <a class="button-style-1" href="/">Upload</a>
            <a class="button-style-1" href="/download/files">Download</a>
        </h2>
        <hr style="width: 90%; height: 2px; background-color: black;">
        <div class="download-group">
            <h2 style="text-align: center">Uploaded Files</h2>
            <div class="table-container">
                <table class="customTable">
                    <thead>
                    <tr>
                        <th>No</th>
                        <th>Filename</th>
                        <th>Download</th>
                    </tr>
                    </thead>
                    <tbody>
                    <tr th:each="files, rowStat: ${files}">
                    <tr th:each="file, rowStat: ${files}">
                        <td th:text="${rowStat.count}">1</td>
                        <td th:text="${file.fileInfoName}">File-Name</td>
                        <td><a class="download-button" th:href="${file.fileURL}">Link</a></td>
                    </tr>
                    </tbody>
                </table>
            </div>
        </div>
    </div>
</div>
<footer id="footer">
    <div id="footer-content">
        <p>Copyright ©2022 All rights reserved |</p>
        <p title="Popa Catalin">&nbsp;Popa Catalin</p>
    </div>
</footer>
</body>
</html>

现在,运行 UploadAndDownloadApplication 并转到 localhost:8888 并查看以下输出。

 

 

 

通过这种方式,我们学会了如何从/向数据库上传、下载文件。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值