返回顶部
首页 > 资讯 > 数据库 >JavaWeb开发 —— SpringBootWeb综合案例
  • 755
分享到

JavaWeb开发 —— SpringBootWeb综合案例

mybatisjavamysql 2023-09-26 06:09:33 755人浏览 八月长安
摘要

通过综合案例,我们来了解和学习在开发WEB程序时,前端程序和后端程序以及数据库三者之间是如何交互、如何协作的,而通过综合案例也来掌握通过接口文档开发服务端接口的能力。 目录 一、准备工作 1. 需求说明 2. 环境搭建 3. 开发规范 二、

通过综合案例,我们来了解和学习开发WEB程序时,前端程序和后端程序以及数据库三者之间是如何交互、如何协作的,而通过综合案例也来掌握通过接口文档开发服务端接口的能力。

目录

一、准备工作

1. 需求说明

2. 环境搭建

3. 开发规范

二、部门管理

1. 查询部门

2. 前后端联调

3. 删除部门

4. 新增部门

三、员工管理

1. 分页查询

2. PageHelper分页插件

3. 条件分页查询

4. 删除员工

四、员工信息

1. 新增员工

2. 文件上传

2.1  简介

2.2  本地存储

2.3  阿里云OSS

3. 修改员工

3.1  查询回显

3.2  修改员工信息

五、配置文件

1. 参数配置化

2. yml配置文件

3. @ConfigurationProperties注解 


一、准备工作

1. 需求说明

部门管理:

  • 杏询部门列表
  • 删除部门
  • 新增部门
  • 修改部门

员工管理:

  • 查询员工列表(分页、条件)
  • 删除员工
  • 新增员工
  • 修改员工

2. 环境搭建

  • 准备数据库表(dept、emp) 。
    -- 部门管理create table dept(    id int unsigned primary key auto_increment comment '主键ID',    name varchar(10) not null unique comment '部门名称',    create_time datetime not null comment '创建时间',    update_time datetime not null comment '修改时间') comment '部门表';insert into dept (id, name, create_time, update_time) values(1,'学工部',now(),now()),(2,'教研部',now(),now()),(3,'咨询部',now(),now()), (4,'就业部',now(),now()),(5,'人事部',now(),now());-- 员工管理(带约束)create table emp (  id int unsigned primary key auto_increment comment 'ID',  username varchar(20) not null unique comment '用户名',  passWord varchar(32) default '123456' comment '密码',  name varchar(10) not null comment '姓名',  gender tinyint unsigned not null comment '性别, 说明: 1 男, 2 女',  image varchar(300) comment '图像',  job tinyint unsigned comment '职位, 说明: 1 班主任,2 讲师, 3 学工主管, 4 教研主管, 5 咨询师',  entrydate date comment '入职时间',  dept_id int unsigned comment '部门ID',  create_time datetime not null comment '创建时间',  update_time datetime not null comment '修改时间') comment '员工表';INSERT INTO emp(id, username, password, name, gender, image, job, entrydate,dept_id, create_time, update_time) VALUES(1,'jinyong','123456','金庸',1,'1.jpg',4,'2000-01-01',2,now(),now()),(2,'zhangwuji','123456','张无忌',1,'2.jpg',2,'2015-01-01',2,now(),now()),(3,'yangxiao','123456','杨逍',1,'3.jpg',2,'2008-05-01',2,now(),now()),(4,'weiyixiao','123456','韦一笑',1,'4.jpg',2,'2007-01-01',2,now(),now()),(5,'changyuchun','123456','常遇春',1,'5.jpg',2,'2012-12-05',2,now(),now()),(6,'xiaozhao','123456','小昭',2,'6.jpg',3,'2013-09-05',1,now(),now()),(7,'jixiaofu','123456','纪晓芙',2,'7.jpg',1,'2005-08-01',1,now(),now()),(8,'zhouzhiruo','123456','周芷若',2,'8.jpg',1,'2014-11-09',1,now(),now()),(9,'dingminjun','123456','丁敏君',2,'9.jpg',1,'2011-03-11',1,now(),now()),(10,'zhaomin','123456','赵敏',2,'10.jpg',1,'2013-09-05',1,now(),now()),(11,'luzhangke','123456','鹿杖客',1,'11.jpg',5,'2007-02-01',3,now(),now()),(12,'hebiweng','123456','鹤笔翁',1,'12.jpg',5,'2008-08-18',3,now(),now()),(13,'fangdongbai','123456','方东白',1,'13.jpg',5,'2012-11-01',3,now(),now()),(14,'zhangsanfeng','123456','张三丰',1,'14.jpg',2,'2002-08-01',2,now(),now()),(15,'yulianzhou','123456','俞莲舟',1,'15.jpg',2,'2011-05-01',2,now(),now()),(16,'songyuanqiao','123456','宋远桥',1,'16.jpg',2,'2007-01-01',2,now(),now()),(17,'chenyouliang','123456','陈友谅',1,'17.jpg',NULL,'2015-03-21',NULL,now(),now());
  • 创建SpringBoot工程,引入对应的起步依赖(web、mybatisMysql驱动、lombok)配置文件。
  • application.properties中引入mybatis的配置信息,准备对应的实体类。
  • 准备对应的Mapper、Service(接口、实现类)、Controller基础结构。

3. 开发规范

案例基于当前最为主流的前后端分离模式进行开发。在开发每一功能接口时仔细阅读接口文档并严格遵守接口文档进行开发,才能保证我们开发的功能可以顺利与前端对接。而在本案例中,前后端交互使用的是 Restful 风格接口

REST (REpresentational State Transfer),表述性状态转换,它是一种软件架构风格

  • 传统风格:
    Http://localhost : 8080/user/getById?id=1  //GET:查询ia为1的用户http://localhost : 8080/user/saveUser      //POST:新增用户http://localhost :8080/user/updateUser    //POST:修改用户http://localhost :8080/user/deleteUser?id=1 //GET:删除id为1的用户
  • REST风格:URL定位资源、HTTP动词描述操作
    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的用户

注意事项:

  • REST是风格,是约定方式,约定不是规定,可以打破。
  • 描述模块的功能通常使用复数,也就是加s的格式来描述,表示此类资源,而非单个资源。如:users、emps、books ...
@Data@NoArgsConstructor@AllArgsConstructorpublic class Result {    private Integer code;//响应码,1 代表成功; 0 代表失败    private String msg;  //响应信息 描述字符串    private Object data; //返回的数据    //增删改 成功响应    public static Result success(){        return new Result(1,"success",null);    }    //查询 成功响应    public static Result success(Object data){        return new Result(1,"success",data);    }    //失败响应    public static Result error(String msg){        return new Result(0,msg,null);    }}

二、部门管理

1. 查询部门

  • 查询全部数据(由于部门数据比较少,不考虑分页)。

@RestControllerpublic class DeptController {    @Autowired    private DeptService deptService;    //@RequestMapping(value = "/depts",method = RequestMethod.GET); 指定请求方式为GET    @GetMapping("/depts")    public Result list(){        //调用Service查询部门数据        List deptList = deptService.list();        return Result.success(deptList);    }}public interface DeptService {        List list();}@Servicepublic class DeptServiceImpl implements DeptService {    @Autowired    private DeptMapper deptMapper;        @Override    public List list() {        return deptMapper.list();    }}@Mapperpublic interface DeptMapper {        @Select("select * from dept;")    List list();   }

2. 前后端联调

  • 将资料中提供的 "前端工程" 文件夹中的压缩包,拷贝到一个没有中文不带空格的目录下,解压 nginv-1.22.0-tlias.zip。
  • 启动Nginx,访问测试http://localhost:90/

3. 删除部门

  • 弹出确认框,提示 "您确定要删除该部门的信息吗?" 如果选择确定,则删除该部门,删除成功后,重新刷新列表页面。如果选择了取消,则不执行任何操作。

@RestControllerpublic class DeptController {    @Autowired    private DeptService deptService;         @DeleteMapping("/depts/{id}")    public Result delete(@PathVariable Integer id){        //log.info("根据id删除部门:{}",id);        //调用Service删除部门数据        deptService.delete(id);        return Result.success();    }}public interface DeptService {        void delete(Integer id);}@Servicepublic class DeptServiceImpl implements DeptService {    @Autowired    private DeptMapper deptMapper;        @Override    public void delete(Integer id) {        deptMapper.deleteById(id);    }}@Mapperpublic interface DeptMapper {        @Delete("delete from dept where id = #{id}")    void deleteById(Integer id);   }

4. 新增部门

  • 点击新增部门,会打开新增部门的页面。
  • 部门名称,必填,唯一,长度为2-10位。

@RestControllerpublic class DeptController {    @Autowired    private DeptService deptService;         @PostMapping("/depts")    public Result add(@RequestBody Dept dept){        //log.info("新增部门:{}",dept);        //调用Service新增部门数据        deptService.add(dept);        return Result.success();    }}public interface DeptService {        void add(Dept dept);}@Servicepublic class DeptServiceImpl implements DeptService {    @Autowired    private DeptMapper deptMapper;        @Override    public void add(Dept dept) {        dept.setCreateTime(LocalDateTime.now());        dept.setUpdateTime(LocalDateTime.now());        deptMapper.insert(dept);    }}@Mapperpublic interface DeptMapper {        @Insert("insert into dept(name,create_time,update_time) values(#{name},#{createTime},#{updateTime}) ")    void insert(Dept dept);}

三、员工管理

1. 分页查询

  • 设置请求参数默认值:@RequestParam(defaultvalue="7")

 在之前的mysql学习中,我们知道使用 limit 关键字 实现分页查询。

服务端给客户端响应数据最终是我们所设置的Controller方法的返回值,而一个方法只能有一个返回值,而员工列表和记录数类型不一样,所以我们需要将这两项数据封装成一个实现类。

@Datepublic class PageBean{       private Long tocal;   //总记录数       private List rows;    //当前页数据列表}

//@Slf4j  - lombok日志@RestControllerpublic class EmpController {    @Autowired    private EmpService empService;    @GetMapping("/emps")    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);    }}public interface EmpService {        PageBean page(Integer page , Integer pageSize);}@Servicepublic class EmpServiceImpl implements EmpService {    @Autowired    private EmpMapper empMapper;    @Override    public PageBean page(Integer page, Integer pageSize) {        //获取总记录数        Long count = empMapper.count();        //获取分页查询结果列表        Integer start = (page - 1) * pageSize;        List empList = empMapper.page(start,pageSize);        //封装pagebean对象        PageBean pageBean = new PageBean(count,empList);        return pageBean;    }}@Mapperpublic interface EmpMapper {        @Select("select count(*) from emp")    public Long count();        @Select("select * from emp limit #{start},#{pageSize}")    public List page(Integer start,Integer pageSize);}

2. PageHelper分页插件

在上述分页查询操作中,我们定义两条sql语句获取指定页码数据列表和总记录数,这是原始的分页查询方式,可以看到步骤固定,代码繁琐。

所以第三方组织就提供了专门实现分页查询操作功能的插件,而目前MyBatis框架中最流行的就是PageHelper分页插件 

  • 引入依赖:
                        com.GitHub.pagehelper            pagehelper-spring-boot-starter            1.4.2        
  • 分页代码:
    @Servicepublic class EmpServiceImpl implements EmpService {@Autowiredprivate EmpMapper empMapper;    @Override    public PageBean page(Integer page, Integer pageSize){        //设置分页参数    PageHelper.startPage(page,pageSize);        //执行查询        List empList = empMapper.list();        Page p = (Page) empList;        //封装pagebean对象        PageBean pageBean = new PageBean(p.getTotal(),p.getResult());        return pageBean;    }}@Mapperpublic interface EmpMapper {    @Select("select * from emp")    public List list();}

3. 条件分页查询

 在上述分页查询代码基础上添加条件即可。

@RestControllerpublic class EmpController {    @Autowired    private EmpService empService;    @GetMapping("/emps")    public Result page(            @RequestParam(defaultValue = "1") Integer page,            @RequestParam(defaultValue = "10") Integer pageSize,            String name, Short gender,            @DateTimeFORMat(pattern = "yyyy-MM-dd") LocalDate begin,            @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate end){        //log.info("分页查询:参数:{},{},{},{},{},{}",page,pageSize,name,gender,begin,end);        //调用Service分页查询       PageBean pageBean = empService.page(page,pageSize,name,gender,begin,end);       return Result.success(pageBean);    }}public interface EmpService {        PageBean page(Integer page , Integer pageSize,String name, Short gender,LocalDate begin, LocalDate end);}@Servicepublic class EmpServiceImpl implements EmpService {@Autowiredprivate EmpMapper empMapper;    @Override    public PageBean page(Integer page, Integer pageSize, String name, Short gender, LocalDate begin, LocalDate end){        //设置分页参数    PageHelper.startPage(page,pageSize);        //执行查询        List empList = empMapper.list(name, gender, begin, end);        Page p = (Page) empList;        //封装pagebean对象        PageBean pageBean = new PageBean(p.getTotal(),p.getResult());        return pageBean;    }}@Mapperpublic interface EmpMapper {    public List list(String name, Short gender, LocalDate begin, LocalDate end);}                 select *        from emp                                    name like concat('%', #{name}, '%')                                        and gender = #{gender}                                        and entrydate between #{begin} and #{end}                            order by update_time desc    

4. 删除员工

 思考问题:是否要开发删除和批量删除两个接口?

  • 如果我们仅仅开发一个批量删除的接口是可行的,因为删除一条元素也是特殊的批量删除。

@RestControllerpublic class EmpController {    @Autowired    private EmpService empService;        @DeleteMapping("/emps/{ids}")    public Result delete(@PathVariable List ids){        //log.info("删除员工:{},",ids);        empService.delete(ids);        return Result.success();    }}public interface EmpService {    void delete(List ids);}@Servicepublic class EmpServiceImpl implements EmpService {@Override    public void delete(List ids) {        empMapper.delete(ids);    }}@Mapperpublic interface EmpMapper {    void delete(List ids);}                 delete        from emp        where id in                    #{id}            

四、员工信息

1. 新增员工

 该小节我们针对于员工基本信息的录入,图像的上传第二小节再进行仔细介绍。

@RestControllerpublic class EmpController {    @Autowired    private EmpService empService;        @PostMapping("/emps")    public Result save(@RequestBody Emp emp){         //log.info("新增员工:{},",emp);        empService.save(emp);        return Result.success();    }}public interface EmpService {     void save(Emp emp);}@Servicepublic class EmpServiceImpl implements EmpService {@Override    public void save(Emp emp) {        emp.setCreateTime(LocalDateTime.now());        emp.setUpdateTime(LocalDateTime.now());        empMapper.insert(emp);    }}@Mapperpublic interface EmpMapper {    void delete(List ids);}@Mapperpublic interface EmpMapper {@Insert("insert into emp(username, name, gender, image, job, entrydate, dept_id, create_time, update_time) " +            "values (#{username},#{name},#{gender},#{image},#{job},#{entrydate},#{deptId},#{createTime},#{updateTime})")    void insert(Emp emp);}

2. 文件上传

2.1  简介

  • 文件上传,是指将本地图片、视频、音频等文件上传到服务器,供其他用户浏览或下载的过程。
  • 文件上传在项目中应用非常广泛,我们经常发微博、发微信朋友圈都用到了文件上传功能。

① 前端在进行文件上传时,需注意三要素:

  • 表单项 type= " file "
  • 表单提交方式 post
  • 表单的enctype属性 multipart/form-data
姓名: 年龄:
头像:

② 服务端接收文件:MultipartFile

//@slf4j@RestControllerpublic class UploadController {    @PostMapping("/upload")    public Result upload(String username, Integer age, MultipartFile image){        //log.info("文件上传:{},{},{}",username,age,image);        return Result.success();    }}

2.2  本地存储

在服务端,接收到上传上来的文件之后,将文件存储在本地服务器磁盘中。

MultipartFile 常用方法:

方法说明
String getOriginalFilename() ;获取原始文件名。
void transferTo(File dest) ;将接收的文件转存到磁盘文件中。
long getSize() ;获取文件的大小,单位:字节。
byte[] getBytes() ;获取文件内容的字节数组
lnputStream getInputStream() ;获取接收到的文件内容的输入流。
@RestControllerpublic class UploadController {    @PostMapping("/upload")    public Result upload(String username, Integer age, MultipartFile image) throws IOException {        //log.info("文件上传:{},{},{}",username,age,image);        //获取原始文件名 - 1.jpg        String  originalFilename= image.getOriginalFilename();        //构造唯一文件名(不重复)-- uuid(通用唯一识别码)       int index =  originalFilename.lastIndexOf(".");       String extname  = originalFilename.substring(index);       String newFileName = UUID.randomUUID().toString() + extname;       //log.info("新的文件名:{}" , newFileName);        //将文件存储在服务器的磁盘目录中 F:\downloadfile\upload        image.transferTo(new File("F:\\downloadfile\\upload\\"+newFileName));        return Result.success();    }}

在SpringBoot中,文件上传,默认单个文件允许最大大小为 1M。如果需要上传大文件,可以进行如下配置:

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

注意问题:本地存储指将我们上传的文件全部存储在本地磁盘目录当中,但是这种方式在我们实际开发中很少使用,原因如下:

  • 全部存储在磁盘目录下,前端页面无法直接访问。
  • 项目中上传大量文件到本地磁盘目录下,而磁盘容量有限且不方便扩容又或者磁盘发生错误,损失较大。

2.3  阿里云OSS

① 介绍:

  • 阿里云是阿里巴巴集团旗下全球领先的云计算公司,也是国内最大的云服务提供商。
  • 阿里云对象存储OSS (Object Storage Service),是一款海量、安全、低成本、高可靠的云存储服务。使用OSS,您可以通过网络随时存储和调用包括文本、图片、音频和视频等在内的各种文件。
  • 官网:https://www.aliyun.com/
  • 使用步骤:

Bucket:存储空间是用户用于存储对象(Object,就是文件)的容器,所有的对象都必须隶属于某个存储空间。
SDK:Software Development Kit的缩写,软件开发工具包,包括辅助软件开发的依赖(jar包)、代码示例等,都可以叫做SDK。

② 安装:参照官方SDK编写入门程序:阿里云对象存储OSS简介

  • 添加依赖:
                        com.aliyun.oss            aliyun-sdk-oss            3.15.1                            javax.xml.bind            jaxb-api            2.3.1                            javax.activation            activation            1.1.1                                    org.glassfish.jaxb            jaxb-runtime            2.3.3        
  • 简单上传文件流代码:
    import com.aliyun.oss.ClientException;import com.aliyun.oss.OSS;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.FileInputStream;import java.io.InputStream;public class Demo {    public static void main(String[] args) throws Exception {        // Endpoint以华东1(杭州)为例,其它Region请按实际情况填写。        String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";        // 阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。        String accessKeyId = "yourAccessKeyId";        String accessKeySecret = "yourAccessKeySecret";        // 填写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, accessKeyId, accessKeySecret);        try {            InputStream inputStream = new FileInputStream(filePath);            // 创建PutObjectRequest对象。            PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, objectName, inputStream);            // 设置该属性可以返回response。如果不设置,则返回的response为空。            putObjectRequest.setProcess("true");            // 创建PutObject请求。            PutObjectResult result = ossClient.putObject(putObjectRequest);            // 如果上传成功,则返回200。            System.out.println(result.getResponse().getStatusCode());        } 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();            }        }    }} 

③ 项目集成:

  • 引入阿里云OSS上传文件工具类(由官方的示例代码改造而来)
    package com.itheima.utils;import com.aliyun.oss.OSS;import com.aliyun.oss.OSSClientBuilder;import org.springframework.stereotype.Component;import org.springframework.web.multipart.MultipartFile;import java.io.*;import java.util.UUID;@Componentpublic class AliOSSUtils {    private String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";    private String accessKeyId = "LTAI5tMXhdNWon5c2k4fbSd4";    private String accessKeySecret = "3fleUo57n8X42mijz6WsCUKznmumw8";    private String bucketName = "web-tlias";        public String upload(MultipartFile file) throws IOException {        // 获取上传的文件的输入流        InputStream inputStream = file.getInputStream();        // 避免文件覆盖        String originalFilename = file.getOriginalFilename();        String fileName = UUID.randomUUID().toString() + originalFilename.substring(originalFilename.lastIndexOf("."));        //上传文件到 OSS        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);        ossClient.putObject(bucketName, fileName, inputStream);        //文件访问路径        String url = endpoint.split("//")[0] + "//" + bucketName + "." + endpoint.split("//")[1] + "/" + fileName;        // 关闭ossClient        ossClient.shutdown();        return url;// 把上传到oss的路径返回    }}
  • 上传图片接口开发
    //@slf4j@RestControllerpublic class UploadController {    @Autowired    private AliOSSUtils aliOSSUtils;    //阿里云oss上传文件    @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);    }}

3. 修改员工

3.1  查询回显

@RestControllerpublic class EmpController {    @Autowired    private EmpService empService;        @GetMapping("/emps/{id}")    public Result getById(@PathVariable Integer id){        //log.info("根据id查询员工信息:{}",id);        Emp emp = empService.getById(id);        return Result.success(emp);    }}public interface EmpService {    Emp getById(Integer id);}@Servicepublic class EmpServiceImpl implements EmpService {@Override    public Emp getById(Integer id) {        return empMapper.getById(id);    }}@Mapperpublic interface EmpMapper {    void delete(List ids);}@Mapperpublic interface EmpMapper { @Select("select * from emp where id = #{id}")    Emp getById(Integer id);}

3.2  修改员工信息

@RestControllerpublic class EmpController {    @Autowired    private EmpService empService;    @PostMapping("/emps")    public Result update(@RequestBody Emp emp){        //log.info("更新员工信息:{}",emp);        empService.update(emp);        return Result.success();    }}public interface EmpService {    void update(Emp emp);}@Servicepublic class EmpServiceImpl implements EmpService {@Override    public void update(Emp emp) {        emp.setUpdateTime(LocalDateTime.now());        empMapper.update(emp);    }}@Mapperpublic interface EmpMapper {    void delete(List ids);}              update emp                    username = #{username},            password = #{password},            name = #{name},            gender = #{gender},            image = #{image},            job = #{job},            entrydate = #{entrydate},            dept_id = #{deptId},            update_time = #{updateTime}                where id = #{id}    

五、配置文件

1. 参数配置化

问题分析:上章节中我们采用了阿里云OSS工具类上传文件,在文件上传中我们定义了许多参数,比如阿里云域名、密钥以及存储空间名等。而在之前的开发中我们采用的是硬编码,就会产生问题:不方便维护和管理。

解决方案:我们可以把阿里云OSS工具类参数定义在properties配置文件当中。

#阿里云oss配置文件aliyun.oss.endpoint=https://oss-cn-hangzhou.aliyuncs.comaliyun.oss.accessKeyId=LTAI5tMXhdNWon5c2k4fbSd4aliyun.oss.accessKeySecret=3fleUo57n8X42mijz6WsCUKznmumw8aliyun.oss.bucketName=web-tlias
@Componentpublic class AliOSSUtils {    @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;}

2. yml配置文件

在SpringBoot项目当中支持多种配置方式文件,在之前的学习过程当中,我们一直使用的都是application.properties配置文件,配置文件名是固定的。其实还要其他类型的配置文件:

类别内容对比
xml臃肿
properties层次结构不清晰

yml / yaml (推荐)

简洁、数据为中心

 ① 基本语法:

  • 大小写敏感。
  • 数值前边必须有空格,作为分隔符。
  • 使用缩进表示层级关系,缩进时,不允许使用Tab键,只能用空格。(idea中会自动将Tab转换为空格)
  • 缩进的空格数目不重要,只要相同层级的元素左侧对齐即可。
  • #表示注释,从这个字符一直到行尾, 都会被解析器忽略。

② yml数据格式:

  • 对象 / Map集合
    user:  name: zhangsan  age: 18  password: 123456
  • 数组 / List / Set集合:
    hobby:  - java  - game  - sport

 ③ yml配置:在application.yml中配置上述案例相关的配置项。

spring:  # 数据库连接信息  datasource:    driver-class-name: com.mysql.cj.jdbc.Driver    url: jdbc:mysql://localhost:3306/tlias    username: root    password: 123456  # 文件上传配置  servlet:    multipart:      max-file-size: 10MB      max-request-size: 100MB# Mybatis配置mybatis:  configuration:    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl    map-underscore-to-camel-case: true# 阿里云oss配置aliyun:  oss:    endpoint: https://oss-cn-hangzhou.aliyuncs.com    accessKeyId: LTAI5tMXhdNWon5c2k4fbSd4    accessKeySecret: 3fleUo57n8X42mijz6WsCUKznmumw8    bucketName: web-tlias

3. @ConfigurationProperties注解 

① 问题分析:

在前面的学习时,我们将阿里云oss中四个参数属性交给properties或者yaml配置文件集中的配置管理,而在工具类中我们要想用到这四个参数就需要在成员变量前加上 @Value注解来注入外部配置文件中的属性值,并且在 @Value注解中使用 ${ } 来指定我们注入的指定值。

 但是在实际开发中,如果参数较多,在每一个成员变量前都加上 @Value注解就会繁琐。所以我们又引入了 @ConfigurationProperties注解

@Component@ConfigurationProperties(prefix = "aliyun.oss")public class AliOSSProperties {    private String endpoint;    private String accessKeyId;    private String accessKeySecret;    private String bucketName;    public AliOSSProperties() {    }    public AliOSSProperties(String endpoint, String accessKeyId, String accessKeySecret, String bucketName) {        this.endpoint = endpoint;        this.accessKeyId = accessKeyId;        this.accessKeySecret = accessKeySecret;        this.bucketName = bucketName;    }    public String getEndpoint() {        return endpoint;    }    public void setEndpoint(String endpoint) {        this.endpoint = endpoint;    }    public String getAccessKeyId() {        return accessKeyId;    }    public void setAccessKeyId(String accessKeyId) {        this.accessKeyId = accessKeyId;    }    public String getAccessKeySecret() {        return accessKeySecret;    }    public void setAccessKeySecret(String accessKeySecret) {        this.accessKeySecret = accessKeySecret;    }    public String getBucketName() {        return bucketName;    }    public void setBucketName(String bucketName) {        this.bucketName = bucketName;    }    @Override    public String toString() {        return "AliOSSProperties{" +                "endpoint='" + endpoint + '\'' +                ", accessKeyId='" + accessKeyId + '\'' +                ", accessKeySecret='" + accessKeySecret + '\'' +                ", bucketName='" + bucketName + '\'' +                '}';    }}
@Componentpublic class AliOSSUtils {    @Autowired    private AliOSSProperties aliOSSProperties;        public String upload(MultipartFile file) throws IOException {        //获取阿里云oss参数        String endpoint = aliOSSProperties.getEndpoint();        String accessKeyId = aliOSSProperties.getAccessKeyId();        String accessKeySecret = aliOSSProperties.getAccessKeySecret();        String bucketName = aliOSSProperties.getBucketName();}

注意:当我们完成上述操作时,会发现弹出下面提示框,我们可以添加依赖解决问题。但是这个是可选操作,并不影响我们代码的运行。

            org.springframework.boot            spring-boot-configuration-processor

② @ConfigurationProperties与@Value 对比:

相同点
  • 都是用来注入外部配置的属性的。
不同点
  • @Value注解只能一一个一个的进行外部属性的注入。
  • @ConfigurationProperties'可以批量的将外部的属性配置注入到bean对象的属性中。

来源地址:https://blog.csdn.net/hdakj22/article/details/130259507

您可能感兴趣的文档:

--结束END--

本文标题: JavaWeb开发 —— SpringBootWeb综合案例

本文链接: https://lsjlt.com/news/418126.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作