文章目录
- 一、需求&开发流程
- 二、环境搭建&数据库准备
- 三、部门管理
- 四、员工管理
-
- [4.1 分页(条件)查询](#4.1 分页(条件)查询)
- [4.2 批量删除员工](#4.2 批量删除员工)
- 五、文件上传
-
- [5.1 介绍](#5.1 介绍)
- [5.2 本地存储](#5.2 本地存储)
- [5.3 阿里云OSS](#5.3 阿里云OSS)
-
- [1. 开通OSS](#1. 开通OSS)
- [2. 创建存储空间Bucket](#2. 创建存储空间Bucket)
- [5.4 OSS快速入门](#5.4 OSS快速入门)
- [5.5 OSS上传显示文件](#5.5 OSS上传显示文件)
- 六、配置文件
-
- [6.1 yml配置](#6.1 yml配置)
- [6.2 @ConfigurationProperties](#6.2 @ConfigurationProperties)
- 总结
-
- [第三方服务-通用思路 SDK](#第三方服务-通用思路 SDK)
- yml配置文件全
一、需求&开发流程
Github项目:Springboot3+Mybatis 基础管理系统
- 部门管理
- 查询部门列表
- 删除部门
- 新增部门
- 修改部门
- 员工管理
- 查询员工列表(分页、条件)
- 删除员工
- 新增员工
- 修改员工
- 文件上传
-
查看页面原型明确需求
- 根据页面原型和需求,进行表结构设计、编写接口文档
-
阅读接口文档
-
思路分析
-
功能接口开发
- 就是开发后台的业务功能,一个业务功能,我们称为一个接口
-
功能接口测试
- 功能开发完毕后,先通过Postman进行功能接口测试,测试通过后,再和前端进行联调测试
-
前后端联调测试
- 和前端开发人员开发好的前端工程一起测试
二、环境搭建&数据库准备
实体类:
java
@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;
}
java
@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; //LocalDate
private Integer deptId;
private LocalDateTime createTime;//LocalDateTime
private LocalDateTime updateTime;//LocalDateTime
private static final long serialVersionUID = 1L;
}
步骤: 【SpringBoot3+Mybatis】框架快速搭建
- 准备数据库表(dept、emp)
- 创建springboot工程,引入对应的起步依赖(web、mybatis、mysql驱动、lombok)
- 准备基本工具类 utils.
- 配置文件application.properties中引入mybatis的配置信息,准备对应的实体类
- 准备对应的Mapper、Service(接口、实现类)、Controller基础结构
接口使用REST风格: 【SpringMVC】RESTFul风格设计和实战 第三期
xml
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...
三、部门管理
原型和需求:
LocalDateTime
四、员工管理
4.1 分页(条件)查询
Vo:
java
@Data
@AllArgsConstructor
@NoArgsConstructor
public class EmpVo {
private String name;
private Short gender;
private LocalDate begin;//LocalDate 2024-01-01
private LocalDate end;//LocalDate
private Integer page;
private Integer pageSize;
}
controller
java
@RestController
@RequestMapping("emps")
public class EmpController {
@Autowired
private EmpService empService;
@GetMapping
public Result queryPage(EmpVo empVo){
Result result = empService.queryPage(empVo);
return result;
}
}
service:
java
@Service
public class EmpServiceImpl implements EmpService {
@Autowired
private EmpMapper empMapper;
@Override
public 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
xml
<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 批量删除员工
controller
java
/**
* 批量删除员工的数据信息
* @param ids
* @return
*/
@DeleteMapping("{ids}")
public Result deleteByIds(@PathVariable Integer[] ids){
Result result = empService.deleteByIds(ids);
return result;
}
service
java
@Override
public Result deleteByIds(Integer[] ids) {
int rows = empMapper.deleteByIds(ids);
if (rows > 0) {
return Result.success(null);
}
return Result.error("为空");
}
mapperxml
xml
<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就可以来接收到上传的文件
5.2 本地存储
MultipartFile
常见方法:
java
@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();
}
}
上传大文件时报错:
添加文件上传的容量配置:
yml
spring:
servlet:
multipart:
max-file-size: 10MB #配置单个文件最大上传大小
max-request-size: 100MB #配置单个请求最大上传大小(一次请求可以上传多个文件)
本地存储的问题:
如果直接存储在服务器的磁盘目录中,存在以下缺点:
- 不安全:磁盘如果损坏,所有的文件就会丢失
- 容量有限:如果存储大量的图片,磁盘空间有限(磁盘不可能无限制扩容)
- 无法直接访问
为了解决上述问题呢,通常有两种解决方案:
- 自己搭建存储服务器,如:fastDFS 、MinIO
- 使用现成的云服务,如:阿里云,腾讯云,华为云
5.3 阿里云OSS
1. 开通OSS
2. 创建存储空间Bucket
5.4 OSS快速入门
阿里依赖,具体看官方使用文档:
xml
<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>
案例代码:
java
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();
}
}
}
}
5.5 OSS上传显示文件
在新增员工的时候,上传员工的图像,而之所以需要上传员工的图像,是因为将来我们需要在系统页面当中访问并展示员工的图像。而要想完成这个操作,需要做两件事:
- 需要上传员工的图像,并把图像保存起来(存储到阿里云OSS)
- 访问员工图像(通过图像在阿里云OSS的存储地址访问图像)
- OSS中的每一个文件都会分配一个访问的url,通过这个url就可以访问到存储在阿里云上的图片。所以需要把url返回给前端,这样前端就可以通过url获取到图像。
工具类:(引入外部文件注入,调用get)
java
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 {
//注入配置参数实体类对象
@Autowired
private 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("."));
//上传文件到 OSS
OSS 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;
// 关闭ossClient
ossClient.shutdown();
return url;// 把上传到oss的路径返回
}
}
controller:
java
@RestController
public class UploadController {
@Autowired
private AliOSSUtils aliOSSUtils;
@PostMapping("/upload")
public Result upload(MultipartFile image) throws IOException {
//调用阿里云OSS工具类,将上传上来的文件存入阿里云
String url = aliOSSUtils.upload(image);
//将图片上传完成后的url返回,用于浏览器回显展示
return Result.success(url);
}
}
六、配置文件
6.1 yml配置
yml配置文件中:
yml
aliyun: #以下参数全部修改成自己的
oss:
endpoint: https://oss-cn-fuzhou.aliyuncs.com
accessKeyId: LTAI5t6Av5GLDxX #假的修改
accessKeySecret: C1IrHzKZKvcotD4d5Tc #假的修改
bucketName: web-wake-work
创建实体类存放字段属性:
直接使用注解 @ConfigurationProperties(prefix = "aliyun.oss")
实体类中的属性名 和配置文件当中key 的名字 必须要一致
java
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
添加注解出现红色提示,添加依赖即可
xml
<!-- @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配置文件全
yml
server:
servlet:
context-path: /
spring:
datasource:
# 连接池类型
type: com.alibaba.druid.pool.DruidDataSource # 使用Druid连接池
# Druid的其他属性配置 springboot3整合情况下,数据库连接信息必须在Druid属性下!
druid:
url: jdbc:mysql://localhost:3306/db01_mybatis
username: root
password: root
driver-class-name: com.mysql.cj.jdbc.Driver
servlet:
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.Slf4jImpl
type-aliases-package: com.wake.pojo # 配置别名 批量将包下的类,设置别名都为首字母小写
mapper-locations: classpath:/mappers/*.xml # mapperxml位置
aliyun: #以下参数全部修改成自己的
oss:
endpoint: https://oss-cn-fuzhou.aliyuncs.com
accessKeyId: LTAI5t9ZK8iq5T2Av6GLDxX #假的修改
accessKeySecret: C0IrHKqU8S8YQcevcotD3Zd5Tc #假的修改
bucketName: web-wake-work