【Springboot3+Mybatis】文件上传阿里云OSS 基础管理系统CRUD

文章目录

  • 一、需求&开发流程
  • 二、环境搭建&数据库准备
  • 三、部门管理
  • 四、员工管理
    • 4.1 分页(条件)查询
    • 4.2 批量删除员工
  • 五、文件上传
    • 5.1 介绍
    • 5.2 本地存储
    • 5.3 阿里云OSS
      • 1. 开通OSS
      • 2. 创建存储空间Bucket
    • 5.4 OSS快速入门
    • 5.5 OSS上传显示文件
  • 六、配置文件
    • 6.1 yml配置
    • 6.2 @ConfigurationProperties
  • 总结
    • 第三方服务-通用思路 SDK
    • yml配置文件全


一、需求&开发流程

Github项目:Springboot3+Mybatis 基础管理系统

  1. 部门管理
    • 查询部门列表
    • 删除部门
    • 新增部门
    • 修改部门
  2. 员工管理
    • 查询员工列表(分页、条件)
    • 删除员工
    • 新增员工
    • 修改员工
  3. 文件上传

1

  1. 查看页面原型明确需求

    • 根据页面原型和需求,进行表结构设计、编写接口文档
  2. 阅读接口文档

  3. 思路分析

  4. 功能接口开发

    • 就是开发后台的业务功能,一个业务功能,我们称为一个接口
  5. 功能接口测试

    • 功能开发完毕后,先通过Postman进行功能接口测试,测试通过后,再和前端进行联调测试
  6. 前后端联调测试

    • 和前端开发人员开发好的前端工程一起测试

二、环境搭建&数据库准备

1
实体类:

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Dept implements Serializable {private Integer id;private String name;private LocalDateTime createTime;private LocalDateTime updateTime;private static final long serialVersionUID = 1L;
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Emp implements Serializable {private Integer id;private String username;private String password;private String name;private Integer gender;private String image;private Integer job;private LocalDate entrydate; //LocalDateprivate Integer deptId;private LocalDateTime createTime;//LocalDateTime private LocalDateTime updateTime;//LocalDateTime private static final long serialVersionUID = 1L;
}

步骤: 【SpringBoot3+Mybatis】框架快速搭建

  1. 准备数据库表(dept、emp)
  2. 创建springboot工程,引入对应的起步依赖(web、mybatis、mysql驱动、lombok)
  3. 准备基本工具类 utils.
  4. 配置文件application.properties中引入mybatis的配置信息,准备对应的实体类
  5. 准备对应的Mapper、Service(接口、实现类)、Controller基础结构

接口使用REST风格:【SpringMVC】RESTFul风格设计和实战 第三期

http://localhost:8080/users/1  GET:查询id为1的用户
http://localhost:8080/users    POST:新增用户
http://localhost:8080/users    PUT:修改用户
http://localhost:8080/users/1  DELETE:删除id为1的用户

通过URL定位要操作的资源,通过HTTP动词(请求方式)来描述具体的操作。

注意事项:

  • REST是风格,是约定方式,约定不是规定,可以打破
  • 描述模块的功能通常使用复数,也就是加s的格式来描述,表示此类资源,而非单个资源。如:users、emps、books…

三、部门管理

原型和需求:
1
1
LocalDateTime

四、员工管理

4.1 分页(条件)查询

Vo:

@Data
@AllArgsConstructor
@NoArgsConstructor
public class EmpVo {private String name;private Short gender;private LocalDate begin;//LocalDate  2024-01-01private LocalDate end;//LocalDateprivate Integer page;private Integer pageSize;
}

controller

@RestController
@RequestMapping("emps")
public class EmpController {@Autowiredprivate EmpService empService;@GetMappingpublic Result queryPage(EmpVo empVo){Result result = empService.queryPage(empVo);return result;}
}

service:

@Service
public class EmpServiceImpl implements EmpService {@Autowiredprivate EmpMapper empMapper;@Overridepublic Result queryPage(EmpVo empVo) {if (empVo.getPage() == null || empVo.getPageSize()== null) {PageHelper.startPage(1, 10);}else{PageHelper.startPage(empVo.getPage(),empVo.getPageSize());}List<Emp> empList = empMapper.selectBySelective(empVo);PageInfo<Emp> empPageInfo = new PageInfo<>(empList);Map map = new HashMap();map.put("total",empPageInfo.getTotal());map.put("rows",empList);if (empList.isEmpty()){return Result.error("无");}return Result.success(map);}
}

mapperxml

    <select id="selectBySelective" resultType="com.wake.pojo.Emp">select *from emp<where><if test="empVo.name != null">name like concat('%',#{empVo.name},'%')</if><if test="empVo.gender != null">and gender=#{empVo.gender}</if><if test="empVo.end != null and empVo.begin != null ">and entrydate between #{empVo.begin} and #{empVo.end}</if></where></select>

4.2 批量删除员工

1
controller

    /*** 批量删除员工的数据信息* @param ids* @return*/@DeleteMapping("{ids}")public Result deleteByIds(@PathVariable Integer[] ids){Result result = empService.deleteByIds(ids);return result;}

service

    @Overridepublic Result deleteByIds(Integer[] ids) {int rows = empMapper.deleteByIds(ids);if (rows > 0) {return Result.success(null);}return Result.error("为空");}

mapperxml

    <delete id="deleteByIds">delete from emp where id in<foreach collection="ids" open="(" close=")" separator="," item="id">#{id}</foreach></delete>

五、文件上传

5.1 介绍

Spring中提供了一个API:MultipartFile,使用这个API就可以来接收到上传的文件
1

5.2 本地存储

MultipartFile 常见方法:
1

@Slf4j
@RestController
public class UploadController {@PostMapping("/upload")public Result upload(String username, Integer age, MultipartFile image) throws IOException {log.info("文件上传:{},{},{}",username,age,image);//获取原始文件名String originalFilename = image.getOriginalFilename();//构建新的文件名String extname = originalFilename.substring(originalFilename.lastIndexOf("."));//文件扩展名String newFileName = UUID.randomUUID().toString()+extname;//随机名+文件扩展名//将文件存储在服务器的磁盘目录image.transferTo(new File("E:/images/"+newFileName));return Result.success();}
}

上传大文件时报错:
1
添加文件上传的容量配置:

spring:servlet:multipart:max-file-size: 10MB #配置单个文件最大上传大小max-request-size: 100MB #配置单个请求最大上传大小(一次请求可以上传多个文件)

本地存储的问题:
1

如果直接存储在服务器的磁盘目录中,存在以下缺点:

  • 不安全:磁盘如果损坏,所有的文件就会丢失
  • 容量有限:如果存储大量的图片,磁盘空间有限(磁盘不可能无限制扩容)
  • 无法直接访问

为了解决上述问题呢,通常有两种解决方案:

  • 自己搭建存储服务器,如:fastDFS 、MinIO
  • 使用现成的云服务,如:阿里云,腾讯云,华为云

5.3 阿里云OSS

1

1. 开通OSS

阿里云——官网
1
1

2. 创建存储空间Bucket

1
1

5.4 OSS快速入门

阿里云OSS使用官方文档

阿里依赖,具体看官方使用文档:

        <dependency><groupId>com.aliyun.oss</groupId><artifactId>aliyun-sdk-oss</artifactId><version>3.15.1</version></dependency><dependency><groupId>javax.xml.bind</groupId><artifactId>jaxb-api</artifactId><version>2.3.1</version></dependency><dependency><groupId>javax.activation</groupId><artifactId>activation</artifactId><version>1.1.1</version></dependency><!-- no more than 2.3.3--><dependency><groupId>org.glassfish.jaxb</groupId><artifactId>jaxb-runtime</artifactId><version>2.3.3</version></dependency>

案例代码:

import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.common.auth.*;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.PutObjectRequest;
import com.aliyun.oss.model.PutObjectResult;
import java.io.File;public class Demo {public static void main(String[] args) throws Exception {// Endpoint以华东1(杭州)为例,其它Region请按实际情况填写。String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";// 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();// 填写Bucket名称,例如examplebucket。String bucketName = "examplebucket";// 填写Object完整路径,完整路径中不能包含Bucket名称,例如exampledir/exampleobject.txt。String objectName = "exampledir/exampleobject.txt";// 填写本地文件的完整路径,例如D:\\localpath\\examplefile.txt。// 如果未指定本地路径,则默认从示例程序所属项目对应本地路径中上传文件。String filePath= "D:\\localpath\\examplefile.txt";// 创建OSSClient实例。OSS ossClient = new OSSClientBuilder().build(endpoint, credentialsProvider);try {// 创建PutObjectRequest对象。PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, objectName, new File(filePath));// 如果需要上传时设置存储类型和访问权限,请参考以下示例代码。// ObjectMetadata metadata = new ObjectMetadata();// metadata.setHeader(OSSHeaders.OSS_STORAGE_CLASS, StorageClass.Standard.toString());// metadata.setObjectAcl(CannedAccessControlList.Private);// putObjectRequest.setMetadata(metadata);// 上传文件。PutObjectResult result = ossClient.putObject(putObjectRequest);           } catch (OSSException oe) {System.out.println("Caught an OSSException, which means your request made it to OSS, "+ "but was rejected with an error response for some reason.");System.out.println("Error Message:" + oe.getErrorMessage());System.out.println("Error Code:" + oe.getErrorCode());System.out.println("Request ID:" + oe.getRequestId());System.out.println("Host ID:" + oe.getHostId());} catch (ClientException ce) {System.out.println("Caught an ClientException, which means the client encountered "+ "a serious internal problem while trying to communicate with OSS, "+ "such as not being able to access the network.");System.out.println("Error Message:" + ce.getMessage());} finally {if (ossClient != null) {ossClient.shutdown();}}}
}

1
1

5.5 OSS上传显示文件

在新增员工的时候,上传员工的图像,而之所以需要上传员工的图像,是因为将来我们需要在系统页面当中访问并展示员工的图像。而要想完成这个操作,需要做两件事:

  1. 需要上传员工的图像,并把图像保存起来(存储到阿里云OSS)
  2. 访问员工图像(通过图像在阿里云OSS的存储地址访问图像)
    • OSS中的每一个文件都会分配一个访问的url,通过这个url就可以访问到存储在阿里云上的图片。所以需要把url返回给前端,这样前端就可以通过url获取到图像。

工具类:(引入外部文件注入,调用get)

package com.wake.utils;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;import java.io.IOException;
import java.io.InputStream;
import java.util.UUID;@Component
public class AliOSSUtils {//注入配置参数实体类对象@Autowiredprivate AliOSSProperties aliOSSProperties;/*** 实现上传图片到OSS*/public String upload(MultipartFile multipartFile) throws IOException {// 获取上传的文件的输入流InputStream inputStream = multipartFile.getInputStream();// 避免文件覆盖String originalFilename = multipartFile.getOriginalFilename();String fileName = UUID.randomUUID().toString() + originalFilename.substring(originalFilename.lastIndexOf("."));//上传文件到 OSSOSS ossClient = new OSSClientBuilder().build(aliOSSProperties.getEndpoint(),aliOSSProperties.getAccessKeyId(), aliOSSProperties.getAccessKeySecret());ossClient.putObject(aliOSSProperties.getBucketName(), fileName, inputStream);//文件访问路径String url =aliOSSProperties.getEndpoint().split("//")[0] + "//" + aliOSSProperties.getBucketName() + "." + aliOSSProperties.getEndpoint().split("//")[1] + "/" + fileName;// 关闭ossClientossClient.shutdown();return url;// 把上传到oss的路径返回}
}

controller:

@RestController
public class UploadController {@Autowiredprivate AliOSSUtils aliOSSUtils;@PostMapping("/upload")public Result upload(MultipartFile image) throws IOException {//调用阿里云OSS工具类,将上传上来的文件存入阿里云String url = aliOSSUtils.upload(image);//将图片上传完成后的url返回,用于浏览器回显展示return Result.success(url);}
}

1
1

六、配置文件

6.1 yml配置

yml配置文件中:

aliyun: #以下参数全部修改成自己的oss:endpoint: https://oss-cn-fuzhou.aliyuncs.comaccessKeyId: LTAI5t6Av5GLDxX  #假的修改accessKeySecret: C1IrHzKZKvcotD4d5Tc #假的修改bucketName: web-wake-work

创建实体类存放字段属性:
1
直接使用注解 @ConfigurationProperties(prefix = "aliyun.oss")
实体类中的属性名和配置文件当中key名字必须要一致

package com.wake.utils;import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;@Data
@Component
@ConfigurationProperties(prefix = "aliyun.oss") //这样不用一个一个属性挂载@Value
public class AliOSSProperties {private String endpoint;private String accessKeyId;private String accessKeySecret;private String bucketName;
}

6.2 @ConfigurationProperties

添加注解出现红色提示,添加依赖即可
1

        <!--   @ConfigurationProperties 注解--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId></dependency>
  • @Value注解只能一个一个的进行外部属性的注入。
  • @ConfigurationProperties可以批量的将外部的属性配置注入到bean对象的属性中。
  • 通过 configuration properties 批量的将外部的属性配置直接注入到 bin 对象的属性当中。
  • 在其他的类当中,我要想获取到注入进来的属性,我直接注入 bin 对象,然后调用 get 方法,就可以获取到对应的属性值了

总结

在这里插入图片描述

第三方服务-通用思路 SDK

在这里插入图片描述
SDK:Software Development Kit 的缩写,软件开发工具包,包括辅助软件开发的依赖(jar包)、代码示例等,都可以叫做SDK。

.
简单说,sdk中包含了我们使用第三方云服务时所需要的依赖,以及一些示例代码。我们可以参照sdk所提供的示例代码就可以完成入门程序。

yml配置文件全

server:servlet:context-path: /spring:datasource:# 连接池类型type: com.alibaba.druid.pool.DruidDataSource  # 使用Druid连接池# Druid的其他属性配置 springboot3整合情况下,数据库连接信息必须在Druid属性下!druid:url: jdbc:mysql://localhost:3306/db01_mybatisusername: rootpassword: rootdriver-class-name: com.mysql.cj.jdbc.Driverservlet:multipart:max-file-size: 10MB #配置单个文件最大上传大小max-request-size: 100MB #配置单个请求最大上传大小(一次请求可以上传多个文件)mybatis:configuration:  # setting配置auto-mapping-behavior: full # 开启resultMap自动映射 设置映射等级full 复杂情况也能映射 多表联查相关map-underscore-to-camel-case: true # true开启属性字段驼峰命名自动映射,将xxx_xxx这样的列名自动映射到xxXxx这样驼峰式命名的属性名log-impl: org.apache.ibatis.logging.stdout.StdOutImpl#    log-impl: org.apache.ibatis.logging.slf4j.Slf4jImpltype-aliases-package: com.wake.pojo # 配置别名 批量将包下的类,设置别名都为首字母小写mapper-locations: classpath:/mappers/*.xml # mapperxml位置aliyun: #以下参数全部修改成自己的oss:endpoint: https://oss-cn-fuzhou.aliyuncs.comaccessKeyId: LTAI5t9ZK8iq5T2Av6GLDxX  #假的修改accessKeySecret: C0IrHKqU8S8YQcevcotD3Zd5Tc #假的修改bucketName: web-wake-work

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/284484.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

RocketMq 顺序消费、分区消息、延迟发送消息、Topic、tag分类 实战 (消费者) (三)

消费端配置 如下所示&#xff1a;是消费者的配置类&#xff0c;有以下几点需要注意的地方 1、是TargetMessageListener这个监听类&#xff08;下文会把这个监听类的具体代码贴出来&#xff09;&#xff0c;需要把这个监听类订阅。 2、rocketMqDcProperties.getTargetProperties…

0基础 三个月掌握C语言(13)-下

数据在内存中的存储 浮点数在内存中的存储 常见的浮点数&#xff1a;3.141592、1E10等 浮点数家族包括&#xff1a;float、double、long double类型 浮点数表示的范围&#xff1a;在float.h中定义 练习 关于&#xff08;float*)&n&#xff1a; &n&#xff1a;这是一…

字符串哈希(c++)

1、定义 字符串哈希把不同的字符串映射成不同的整数 1.1、规则 1、把字符串映射成一个P进制数字 对于一个长度为n的字符串s 这样定义Hash函数&#xff1a; 例如&#xff1a;字符串abc&#xff0c;其哈希函数值为ap^2 bp^1 c; 即97 * 131^2 98 * 131^1 99; 2、两个字符串不一…

【计算机网络篇】数据链路层(3)差错检测

文章目录 &#x1f95a;误码&#x1f354;两种常见的检错技术⭐奇偶校验⭐循环冗余校验&#x1f388;例子 &#x1f95a;误码 误码首先介绍误码的相关概念 &#x1f354;两种常见的检错技术 ⭐奇偶校验 奇校验是在待发送的数据后面添加1个校验位&#xff0c;使得添加该校验…

C++|类封装、类的分文件编写练习:设计立方体类、点和圆的关系

文章目录 练习案例1&#xff1a;设计立方体类CPP代码 练习案例2:点和圆的关系CPP代码 代码总结类的分文件编写 练习案例1&#xff1a;设计立方体类 设计立方体类(Cube) 求出立方体的面积和体积 分别用全局函数和成员函数判断两个立方体是否相等。 CPP代码 class Cube { pub…

GPT4.0

GPT4.0 支持官网所有功能以及所有第三方GPTS&#xff0c;完全同步官网。无需魔法&#xff0c;填写授权码直达官网。全天超18小时维护&#xff0c;无需担心不稳定。没有永久卡&#xff0c;3.5免费提供&#xff0c;4.0可以按需下单即可&#xff0c;不存在跑路。 需要的联系

详细安装步骤:vue.js 三种方式安装(vue-cli)

Vue.js&#xff08;读音 /vjuː/, 类似于 view&#xff09;是一个构建数据驱动的 web 界面的渐进式框架。Vue.js 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件。它不仅易于上手&#xff0c;还便于与第三方库或既有项目整合。 三种 Vue.js 的安装方法&…

unity 多屏幕操作

想了解基础操作请移步&#xff1a;&#xff08;重点是大佬写的好&#xff0c;这里就不再赘述&#xff09; Unity 基础 之 使用 Display 简单的实现 多屏幕显示的效果_unity display-CSDN博客 在panel上也可以通过获取 Canvas&#xff0c;来达到切换多屏幕的操作&#xff0c; …

Flutter-仿携程首页类型切换

效果 唠叨 闲来无事&#xff0c;不小心下载了携程app&#xff0c;还幻想可以去旅游一番&#xff0c;奈何自己运气不好&#xff0c;自从高考时第一次吹空调导致自己拉肚子考试&#xff0c;物理&#xff0c;数学考了一半就交卷&#xff0c;英语2B铅笔除了问题&#xff0c;导致原…

行政工作常用表格

企业管制制度大全https://www.chuandao100.com/279.html

JVM垃圾收集器你会选择吗?

目录 一、Serial收集器 二、ParNew收集器 三、Paralle Scavenge 四、Serial Old 五、Parallel Old 六、CMS收集器 6.1 CMS对处理器资源非常敏感 6.2 CMS容易出现浮动垃圾 6.3 产生内存碎片 七、G1 收集器 八、如何选择合适的垃圾收集器 JVM 垃圾收集器是Java虚…

生成模型概述

文章目录 生成模型概述一、生成模型类型二、生成对抗网络&#xff08;GANs&#xff09;三、自回归模型&#xff08;Autoregressive Models&#xff09;四、扩散模型&#xff08;Diffusion Models&#xff09;五、流模型&#xff08;Flow-based Models&#xff09;参考 生成模型…

【数据分享】1929-2023年全球站点的逐日平均海平面压力(Shp\Excel\免费获取)

气象数据是在各项研究中都经常使用的数据&#xff0c;气象指标包括气温、风速、降水、能见度等指标&#xff0c;说到气象数据&#xff0c;最详细的气象数据是具体到气象监测站点的数据&#xff01; 有关气象指标的监测站点数据&#xff0c;之前我们分享过1929-2023年全球气象站…

CPP容器vector和list,priority_queue定义比较器

#include <iostream> #include <bits/stdc.h> using namespace std; struct VecCmp{bool operator()(int& a,int& b){return a>b;/*** 对于vector和list容器&#xff0c;这里写了&#xff1e;就是从大到小* 对于priority_queue容器&#xff0c;这里写…

【阅读论文】When Large Language Models Meet Vector Databases: A Survey

摘要 本调查探讨了大型语言模型&#xff08;LLM&#xff09;和向量数据库&#xff08;VecDB&#xff09;之间的协同潜力&#xff0c;这是一个新兴但迅速发展的研究领域。随着LLM的广泛应用&#xff0c;出现了许多挑战&#xff0c;包括产生虚构内容、知识过时、商业应用成本高昂…

【算法与数据结构】 C语言实现单链表队列详解

文章目录 &#x1f4dd;队列&#x1f320; 数据结构设计&#x1f309;初始化队列函数 &#x1f320;销毁队列函数&#x1f309;入队函数 &#x1f320;出队函数&#x1f309;获取队首元素函数 &#x1f320;获取队尾元素函数&#x1f309; 判断队列是否为空函数&#x1f309;获…

如何让uni-app开发的H5页面顶部原生标题和小程序的顶部标题不一致?

如何让标题1和标题2不一样&#xff1f; 修改根目录下的App.vue&#xff08;核心代码如下&#xff09; <script>export default {onLaunch() {// 监听各种跳转----------------------------------------[navigateTo, redirectTo, reLaunch, switchTab, navigateBack, ].…

Leetcode 226. 翻转二叉树

心路历程&#xff1a; 翻转一瞬间没什么思路&#xff0c;其实就是挨个把每个结点的左右子树都翻转了。主要不要按照左右子树去思考&#xff0c;要按照结点去思考。 翻转既可以从上到下翻转&#xff08;前序遍历&#xff09;&#xff0c;也可以从下到上翻转&#xff08;后序遍历…

等保测评-Windows服务器

安全计算环境 身份鉴别 a)应对登录的用户进行身份标识和鉴别&#xff0c;身份标识具有唯一性&#xff0c;身份鉴别信息具有复杂度要求并定期更换 winr //运行 secpol.msc //本地安全策略&#xff0c;点击账户策略中的密码策略 注意修改的时候确保当前密码是满足条件的 b)应…

应急响应-Linux(1)

应急响应-Linux(1) 黑客的IP地址 思路&#xff1a; 一般系统中马之后会有进程连接黑客的主机&#xff0c;可以使用netstat -anpt查看下当前进程的连接&#xff0c;此处查看到没有后 &#xff0c;可以从系统服务开始查找&#xff0c;系统的服务日志一般都会保存相关访问信息&…