案例:
- 准备数据库表(dept、emp)
- 创建springboot工程,引入对应的起步依赖(web、mybatis、mysql驱动、lombok)
- 配置文件application.properties中引入mybatis的配置信息,准备对应的实体类
- 准备对应的Mapper、Service(接口、实现类)、Controller基础结构
开发规范:Restful
REST(REpresentational State Transfer),表述性状态转换,它是一种软件架构风格
传统风格:
http://localhost:8080/user/getById?id=21 get:查询id为1的用户
http://localhost:8080/user/saveUser post:新增用户
http://localhost:8080/user/updateUser post:修改用户
http://localhost:8080/user/deleteUser?id=1 get:删除id为1的用户
REST风格:
http://localhost:8080/users/1 get:查询id为1的用户
http://localhost:8080/users post:新增用户
http://localhost:8080/users put:修改用户
http://localhost:8080/users1 delete:删除id为1的用户
注意:
- REST是风格,是约定方式,约定不是规定,可以打破
- 描述模块的功能通常使用复数,也就是加s的格式来描述,表示此类资源,而非单个资源。如users、emps、books ……
员工管理-分页查询:
/*
参数1:起始索引 = (页码-1) * 每页展示记录数
参数2:查询返回记录数 = 每页展示记录数
*/
//查询第一页数据,每页展示5条记录
sql:select * from emp limit 0,5
//查询第二页数据,每页展示5条记录
sql:select * from emp limit 5,5
PageBean.java:
@Data
@NoArgsConstructor
@AllArgsConstructor
public class PageBean{
private Long total;//总记录数
private List rows;//数据列表
}
Mapper:
@Mapper
public interface EmpMapper{
//查询总记录数
@Select("select count(*) from emp")
public Long count();
//分页查询,获取列表数据
@Select("select * from emp limit #{start},#{pageSize}")
public List<Emp> page(Integer start,Integer pageSize);
}
Controller:
@Autowired
private EmpService empService;
@GetMapping
public Result page(@RequestParam(defaultValue = "1") Integer page,
@RequestParam(defaultValue = "10") Integer pageSize,)
{
log.info("分页查询, 参数: {},{}",page,pageSize);
//调用service分页查询
PageBean pageBean = empService.page(page,pageSize);
return Result.success(pageBean);
}
service:
@Autowired
private EmpMapper empMapper;
@Override
public PageBean page(Integer page, Integer pageSize) {
//1. 获取总记录数
Long count = empMapper.count();
//2. 获取分页查询结果列表
Integer start = (page - 1) * pageSize;
List<Emp> empList = empMapper.page(start, pageSize);
//3. 封装PageBean对象
PageBean pageBean = new PageBean(count, empList);
return pageBean;
}
分页插件:PageHelper
---------------------------------------------
<!--PageHelper分页插件-->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.4.2</version>
</dependency>
---------------------------------------------
EmpMapper:
//员工信息查询
@Select("select * from emp")
public List<Emp> list();
---------------------------------------------
EmpServiceimpl:
@Override
public PageBean page(Integer page,Integer pageSize){
//1、设置分页参数
PageHelper.startPage(page,pageSize);
//2、执行查询
/*
分页插件自动获取到"select * from emp",把 * 改成 count(*),获取到总页数:
"select count(*) from emp"
然后对sql语句进行改造,自动添加 limit :"select * from emp limit ?,?;"
*/
List<Emp> empList = empMapper.list();
Page<Emp> p = (Page<Emp>) empList;
//3、封装PageBean对象
PageBean pageBean = new PageBean(p.getTotal(),p.getResult());
//p.getTotal(),获取总记录数;p.getResult(),获取分页查询结果列表
return pageBean;
}
---------------------------------------------
文件上传:
- 文件上传,是指将本地图片、视频、音频等文件上传到服务器,供其他用户浏览或下载的过程
- 文件上传在项目中应用非常广泛,我们经常发微博、发微信朋友圈都用到了文件上传功能
总结:
- 前端页面三要素:
表单项 type="file" 表单提交方式 post 表单的enctype属性 multipart/form-data
- 服务端接收文件:
MultipartFile
通过MultipartFile接收的文件是临时文件,当文件上传的请求响应完毕后,临时文件会自动删除
<form action="/upload" method="post" enctype="multipart/form-data">
//enctype 必须要改为"multipart/form-data",才能上传文件内容,
//不能使用默认的,默认的只能上传文件名
姓名: <input type="text" name="username"><br>
年龄: <input type="text" name="age"><br>
头像: <input type="file" name="image"><br>
<input type="submit" value="提交">
</form>
本地存储:
在服务端,接收到上传上来的文件之后,将文件存储在本地服务器磁盘中
UploadController:
//本地存储文件
@PostMapping("/upload")
public Result upload(String username , Integer age , MultipartFile image) throws Exception {
//MultipartFile的名称要跟前端的<input type="file" name="image">名称保持一致,即image
log.info("文件上传: {}, {}, {}", username, age, image);
//获取原始文件名 - 1.jpg 123.0.0.jpg
String originalFilename = image.getOriginalFilename();
//构造唯一的文件名 (不能重复) - uuid(通用唯一识别码) de49685b-61c0-4b11-80fa-c71e95924018
int index = originalFilename.lastIndexOf(".");
//substring字符串截取方法
String extname = originalFilename.substring(index);
String newFileName = UUID.randomUUID().toString() + extname;
log.info("新的文件名: {}", newFileName);
//将文件存储在服务器的磁盘目录中 E:\images
image.transferTo(new File("E:\\images\\"+newFileName));
return Result.success();
}
---------------------------------------------
在springboot中,文件上传,默认单个文件允许最大大小为1M。如果需要上传大文件,可以在配置文件进行如下配置:
---------------------------------------------
# 配置单个文件最大上传大小
spring.servlet.multipart.max-fail-size=10MB
# 配置单个请求最大上传大小(一次请求可以上传多个文件)
spring.servlet.multipart.max-request-size=100MB
---------------------------------------------
MultipartFile常用方法:
- String getOriginalFilename();//获取原始文件名
- void transferTo(File dest);//将接收的文件转存到磁盘文件中
- long geiSize();//获取文件的大小,单位:字节
- byte[] getBytes();//获取文件内容的字节数组
- InputStream getInputStream();//获取接收到的文件内容的输入流
云存储:
阿里云OSS:
阿里云对象存储OSS(Object Storage Service),是一款海量、安全、低成本、高可靠的云存储服务。使用OSS,您可以通过网络随时存储和调用包括文本、图片、音频和视频等在内的各种文件
使用步骤:
1、注册阿里云(实名认证)
2、充值
3、开通对象存储服务(OSS)
4、创建bucket
5、获取AccessKey(密钥)
6、参照官方SDK编写入门程序
7、案例集成OSS
SDK:
Software Development Kit 的缩写,软件开发工具包,包括辅助软件开发的依赖(jar包)、代码示例等,都可以叫做SDK
Bucket:
存储空间是用户用于存储对象(Object,就是文件)的容器,所有的对象都必须隶属于某个存储空间
1、引入依赖:
<!--阿里云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>
2、改动示例代码
……
阿里云OSS-集成:
- 引入阿里云OSS上传文件工具类(由官方的示例代码改造而来)
- 上传图片接口开发
UploadController: @Autowired private AliOSSUtils aliOSSUtils; @PostMapping("/upload") public Result upload(MultipartFile image) throws IOException { log.info("文件上传, 文件名: {}", image.getOriginalFilename()); //调用阿里云OSS工具类进行文件上传 String url = aliOSSUtils.upload(image); log.info("文件上传完成,文件访问的url: {}", url); return Result.success(url); }
修改员工-查询回显:
Controller:
@GetMapping("/{id}")
public Result getById(@PathVariable Integer id){
log.info("根据ID查询员工信息, id: {}",id);
Emp emp = empService.getById(id);
return Result.success(emp);
}
service:
Emp getById(Integer id);
serviceImpl;:
@Override
public Emp getById(Integer id) {
return empMapper.getById(id);
}
Mapper:
@Select("select * from emp where id = #{id}")
Emp getById(Integer id);
配置文件:
@value注解
通常用于外部配置的属性注入,具体用法为: @value (“${配置文件中的key}”)
aliyun.oss.endpoint: https://oss-cn-hangzhou.aliyuncs.com
aliyun.oss.accessKeyId: LTAI4GCH1vX6DKqJWxd6nEuW
aliyun.oss.accessKeySecret: yBshYweHOpqDuhCArrVHwIiBKpyqSL
aliyun.oss.bucketName: web-tlias
@Component
public class AliOSSUtils{
@value("${aliyun.oss.endpoint}")//与配置文件对应
private String endpoint;
}
……
配置格式:
springboot 提供了多种属性配置方式
1、application.properties
server.port=8080
server.address=127.0.0.1
2、application.yml
server:
port: 8080
address: 127.0.0.1
3、application.yaml
server:
port: 8080
address: 127.0.0.1
常见配置文件对比:
1、XML
<server>
<port>8080</port>
<address>127.0.0.1</address>
</server>
2、properties:
server.port=8080
server.address=127.0.0.1
3、yml/yaml
server:
port: 8080
address: 127.0.0.1
yml基本语法:
- 大小写敏感
- 数值前边必须有空格,作为分隔符
- 使用缩进表示层级关系,缩进时,不允许使用Tab键,只能用空格(idea中会自动将Tab转换为空格)
- 缩进的空格数目不重要,只要相同层级的元素左侧对齐即可
- # 表示注释,从这个字符一直到行尾,都会被解析器忽略
对象/Map集合: user: name: zhangsan age: 18 password: 123456 数组/List/Set集合: hobby: - java - game - sport
@ConfigurationProperties:
-------------------------------------
aliyun:
oss:
endpoint: https://oss-cn-hangzhou.aliyuncs.com
accessKeyId: LTAI4GCH1vX6DKqJWxd6nEuW
accessKeySecret: yBshYweHOpqDuhCArrVHwIiBKpyqSL
bucketName: web-tlias
-------------------------------------
@Value("${aliyun.oss.endpoint}")
private String endpoint ;
@Value("${aliyun.oss.accessKeyId}")
private String accessKeyId ;
@Value("${aliyun.oss.accessKeySecret}")
private String accessKeySecret ;
@Value("${aliyun.oss.bucketName}")
private String bucketName ;
每个属性都要用 @value 很麻烦
@Data
@Component
@ConfigurationProperties(prefix = "aliyun.oss")
public class AliOSSProperties{
private String endpoint;
private String accessKeyId;
private String accessKeySecret;
}
注入后,调用相应的get方法获取属性值
注:属性名要与yml的属性名称完全一致
---------------------------------------
加上@ConfigurationProperties 注解后会报警告,引入以下依赖可以取消警告
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
</dependency>
---------------------------------------
@ConfigurationProperties 与 @value:
相同的:
- 都是用来注入外部配置的属性的
不同点:
- @value 注解只能一个一个的进行外部属性的注入
- @ConfigurationProperties 可以批量的将外部的属性配置注入到bean对象的属性中