Java Web —— 第七天(Mybatis案例 员工管理2)

新增员工 

EmpController类
    @PostMapping
    public Result save(@RequestBody Emp emp){
        log.info("新增员工操作,emp:{}",emp);
        empService.save(emp);
        return  Result.success();
    }

EmpServiceImpl实现类
//新增员工
    @Override
    public void save(Emp emp) {
        //补充基础属性 创建和修改属性
        emp.setCreateTime(LocalDateTime.now());
        emp.setUpdateTime(LocalDateTime.now());
        empMapper.insert(emp);
    }
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);

文件上传

文件上传,是指将本地图片、视频、音频等文件上传到服务器,供其他用户浏览或下载的过程

文件上传在项目中应用非常广泛,我们经常发微博、发微信朋友圈都用到了文件上传功能

1. 前端页面三要素、

表单项 type="file"

表单提交方式post

表单的enctype属性multipart/form-data

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>上传文件</title>
</head>
<body>

    <form action="/upload" method="post" 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>

</body>
</html>

2.服务端接收文件

MultipartFile

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

本地存储

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

package com.example.controller;

import com.example.pojo.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.nio.channels.MulticastChannel;
import java.util.UUID;

/**
 * @author hyk~
 */
@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();

        //构造唯一文件名(不能重复) - uuid(通用唯一识别码) ad7088db-9673-433a-bc59-f280dec36fc4
        int index = originalFilename.lastIndexOf(".");
        String extname = originalFilename.substring(index);
        //构建新的文件名
        String newFileName = UUID.randomUUID().toString()+extname;
        log.info("新的文件名:{}",newFileName);


        //将文件存储在磁盘目录中
        image.transferTo(new File("D:\\测试\\"+newFileName));

        return Result.success();
    }

}

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

行如下配置:

#配置单个文件上传大小限制
spring.servlet.multipart.max-file-size=10MB

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

相关方法 

    String getOriginalFilename(); //获取原始文件名
    void transferTo(File dest); //将接收的文件转存到磁盘文件中
    long getSize(); //获取文件的大小,单位: 字节
    byte[] getBytes(); //获取文件内容的字节数组
    InputStream getlnputStream();//获取接收到的文件内容的输入流

阿里云OSS

阿里云对象存储0SS(0bject Storage Service),是一款海量、安全、低成本、高可靠的云存储服务。使用OSS,您可以通过网络随时存储和调用包括文本、图片、音频和视频等在内的各种文件。

阿里云OSS-使用步骤

Bucket: 存储空间是户用于存储对象 (Object,就是文件)的容器,所有的对象都必须隶属于某个存储空间

SDK:Software Developmnt Kit 的缩写,软件开发丁具包,包括辅助软件开发的依赖 (iar包),代码示例等,都可以叫做SDK

安装SDK

方式一: 在Maven项目中加入依赖项 (推荐方式)在Maven工程中使用OSS Java SDK,只需在

pom.xml中加入相应依赖可。以3.15.1版本为例,在<dependencies>中加入如下内容:

        <!--阿里云OSS依赖-->
		<dependency>
			<groupId>com.aliyun.oss</groupId>
			<artifactId>aliyun-sdk-oss</artifactId>
			<version>3.15.1</version>
		</dependency>

代码实现

package com.example.utils;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.web.multipart.MultipartFile;
import java.io.*;
import java.util.UUID;

/**
 * 阿里云 OSS 工具类
 */
@Component
public class AliOSSUtils {

    private String endpoint = "https://oss-cnangzhou.aliyuncs-h.com";
    private String accessKeyId = "LTAI4GCH1vX6DKqJWxd6nEuW";
    private String accessKeySecret = "yBshYweHOpqDuhCArrVHwIiBKpyqSL";
    private String bucketName = "web-tlias";

    /**
     * 实现上传图片到OSS
     */
    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的路径返回
    }

}

Controller类

@Slf4j
@RestController
public class 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);

        //将图片上传后的url返回 用于浏览器回显操作
        return Result.success();
    }


}

小结

1.文件上传介绍

2.前端页面三要素 (file表单项、post方式、multipart/form-data)

3.服务端接收文件(MultipartFile)

4.文件存储方式

本地存储 (无法直接访问、磁盘损坏)磁盘空间限制

云存储OSS

修改员工

数据请求处理类
    //根据id查询数据
    //单条数据用实体类 多条数据用List<实体类类型>集合
    @GetMapping("/{id}")
    public Result selectById(@PathVariable Integer id){
        log.info("根据id查询员工:{}",id);
        Emp emp = empService.select(id);
        return Result.success(emp);
    }

    //修改数据  json格式数据用实体类接收 加注解@RequestBody
    @PutMapping
    public Result updateEmp(@RequestBody Emp emp){
        log.info("需要修改的员工信息:{}",emp);
        empService.updateEmp(emp);
        return Result.success();
    }
业务层实现类
 //根据id查询员工 回显数据
    @Override
    public Emp select(Integer id) {
        Emp emp = empMapper.selectById(id);
        return emp;
    }

    //修改员工数据
    @Override
    public void updateEmp(Emp emp) {
        //设置修改时间为当前
       emp.setUpdateTime(LocalDateTime.now());
        empMapper.updateEmp(emp);
    }
动态SQL
    <!--修改员工数据-->
    <update id="updateEmp">
        update emp
        <set>
            --test当中的属性判断应当与实体类中的属性一致
            <if test="username != null and username != ''">
                username=#{username},
            </if>
            <if test="password != null and password != ''">
                password = #{password},
            </if>
            <if test="name != null and name != ''">
                name=#{name},
            </if>
            <if test="gender != null">
                gender=#{gender},
            </if>
            <if test="image != null and image != null">
                image=#{image},
            </if>
            <if test="job != null">
                job=#{job},
            </if>
            <if test="entrydate != null">
                entrydate=#{entrydate},
            </if>
            <if test="deptId != null">
                dept_id=#{deptId},
            </if>
            <if test="updateTime != null">
            update_time = #{updateTime}
            </if>
        </set>
        where id = #{id}
    </update>
小结
  • 前端输入更新数据:在前端页面输入的数据以JSON格式发送到后端

  • 后端映射为Java实体类:后端通过@RequestBody接收这个JSON数据,并将其映射为对应的Emp实体类对象

  • 判断并生成动态SQL:MyBatis在处理更新操作时,会根据实体类中的属性值进行判断(使用<if>标签中的test条件)。如果某个属性为null或空字符串,则对应的字段不会出现在SQL语句中,也就不会更新数据库中的这个字段;如果不为null或空字符串,则生成的SQL会更新对应的数据库字段。

  • 最终效果:通过这种机制,只有前端传递的非空字段才会更新数据库中的相应字段,而那些为空的字段会保持数据库中原有的值不变

  • 单条数据查询

    • 当查询结果是单条记录时,可以直接用一个实体类对象来接收。这种情况下,查询的SQL语句通常使用select ... where id = ?或其他能确保返回唯一结果的条件。
    • 在MyBatis中,对应的返回类型是Emp
  • 多条数据查询

    • 当查询结果是多条记录时,用List<实体类类型>集合来接收。这种情况下,SQL语句可能是select ... where ...,返回的结果集包含多条记录。
    • 在MyBatis中,对应的返回类型是List<Emp>

@RequestBody@PathVariable的区别

  • 数据来源不同

    • @RequestBody:用于接收请求体中的JSON数据,并将其映射为Java对象(如Emp)。
    • @PathVariable:用于从URL路径中提取单个变量(如ID或其他简单标识符)。
  • 数据结构不同

    • @RequestBody:适用于复杂的对象,例如Emp对象包含多个属性(如nameagegender等),这些属性通常通过JSON传递。
    • @PathVariable:适用于简单标识符,如ID或名称,通常是一两个字符串或数字。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

台球助教在线预约小程序源码开发:打造便捷高效的台球学习新体验

在当今快节奏的生活中&#xff0c;台球作为一项集休闲、竞技与社交于一体的运动&#xff0c;受到了越来越多人的喜爱。然而&#xff0c;对于初学者而言&#xff0c;想要快速提升技能&#xff0c;往往需要专业的指导和陪练。传统的台球教练预约方式往往存在信息不对称、预约流程…

【Qt笔记】Qt界面显示时间

目录 一、前言 二、基本概念 三、代码实现 1. 获取本地时间&#xff0c;并将其转换成自己想要的格式 2.创建一个QLabel控件用于显示时间字符串 3.创建QTimer定时器更新时间 四、优化 1. 格式优化 1.1 初始化 1.2 获取星期 1.3 更改格式 1.4 定时器超时函数 1.5 …

多商户多套部署需修改注意事项

同一台服务器上部署多个多商户项目&#xff0c;需要修改和调整的地方等。 一、修改代码中的端口号&#xff0c;需要两个项目不能使用同一个端口号&#xff0c;例如&#xff1a;A项目用&#xff1a;8324&#xff0c;B项目用&#xff1a;8325&#xff1b; 二、修改反向代理&…

LCP 633 平方数之和 [leetcode - 8]

最近是在研究双指针啊&#xff0c;leetcode刷的题都是这方面的。都记录在最近的文章里&#xff0c;大家有兴趣可以去我主页看看 LCP633 平方数之和 给定一个非负整数 c &#xff0c;你要判断是否存在两个整数 a 和 b&#xff0c;使得 a2 b2 c 。 示例 1&#xff1a; 输入&…

Modbus 数据帧解析

Modbus 是一种通信协议&#xff0c;广泛应用于工业自动化系统中&#xff0c;用于连接电子设备。它是一种基于主从结构的通信协议&#xff0c;其中主设备可以与多个从设备通信。数据通过一系列的帧进行传输&#xff0c;每一帧包含多个字段&#xff0c;每个字段都有特定的功能。 …

HTML 列表和容器元素——WEB开发系列10

HTML 提供了多种方式来组织和展示内容&#xff0c;其中包括无序列表、有序列表、分区元素 ​​<div>​​ 和内联元素 ​​<span>​​、以及如何使用 ​​<div>​​​ 进行布局和表格布局。 一、HTML 列表 1. 无序列表 (​​<ul>​​) 无序列表用于展…

【Win开发环境搭建】Redis与可视化工具详细安装与配置过程

&#x1f3af;导读&#xff1a;本文档提供了Redis的简介、安装指南、配置教程及常见操作方法。包括了安装包的选择与配置环境变量的过程&#xff0c;详细说明了如何通过修改配置文件来设置密码和端口等内容。同时&#xff0c;文档还介绍了如何使用命令行工具连接Redis&#xff…

科研软件 | Diamond 4.6 安装教程

软件介绍 Diamond一个化学专业软件。它是一款在原子水平实现晶体结构可视化的软件&#xff0c;包括分子和聚合物扩展、多面体、搜索结构数据、自动和批量创建结构图片等功能&#xff0c;支持晶体结构着色和渲染以及批注。 软件下载 https://pan.quark.cn/s/37214b5bec7c 软…

05、Redis实战:优惠券秒杀、优化异步下单

6、秒杀优化 6.1 秒杀优化-异步秒杀思路 我们先来回顾一下下单流程当用户发起请求&#xff0c;此时会先请求Nginx&#xff0c;Nginx反向代理到Tomcat&#xff0c;而Tomcat中的程序&#xff0c;会进行串行操作&#xff0c;分为如下几个步骤 查询优惠券判断秒杀库存是否足够查询…

音视频相关知识

H.264编码格式 音频 PCM就是要把声音从模拟信号转换成数字信号的一种技术&#xff0c;他的原理简单地说就是利用一个固定的频率对模拟信号进行采样。 pcm是无损音频音频文件格式 每秒15帧 一秒钟300kb 单位&#xff1a;像素

故障频发,给我一个完美的解释...

1.盘点事故 8月19日&#xff0c;网易云音乐「崩了」&#xff0c;网页端报错&#xff0c;App 无法使用&#xff0c;什么原因&#xff1f;你那受影响了吗&#xff1f; 一次更新&#xff0c;一串代码&#xff0c;全球宕机。7月19日下午发生了全球范围内的Windows大面积蓝屏事件&a…

Django | 从中间件的角度来认识Django发送邮件功能

文章目录 概要中间件中间件 ---> 钩子实现中间件demo 邮件发送过程Django如何做邮件服务配置流程 中间件结合邮件服务实现告警 概要 摘要 业务告警 邮件验证 密码找回 邮件告警 中间件 中间件 —> ‘钩子’ 例如 访问路由 的次数【请求】 中间件类须实现下列五个方法…

C++,std::queue 详解

文章目录 1. 概述2. 包含头文件3. 基本操作3.1 构造函数3.2 赋值操作3.3 成员函数 4. 迭代器5. 示例6. 注意事项参考 1. 概述 std::queue 是 C 标准模板库&#xff08;STL&#xff09;中的一个容器适配器&#xff0c;它提供了一种先进先出&#xff08;FIFO&#xff09;的数据结…

[数据集][目标检测]木材缺陷检测数据集VOC+YOLO格式2383张10类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;2383 标注数量(xml文件个数)&#xff1a;2383 标注数量(txt文件个数)&#xff1a;2383 标注…

网络安全入门教程(非常详细)从零基础入门到精通_网路安全 教程

前言 1.入行网络安全这是一条坚持的道路&#xff0c;三分钟的热情可以放弃往下看了。2.多练多想&#xff0c;不要离开了教程什么都不会了&#xff0c;最好看完教程自己独立完成技术方面的开发。3.有时多百度&#xff0c;我们往往都遇不到好心的大神&#xff0c;谁会无聊天天给…

线性数据结构的基本概念(数组,链表,栈,队列)

数组 数组由相同类型的元素组成&#xff0c;使用一块连续的内存来存储。 数组的特点是&#xff1a; 1.利用索引进行访问 2.容量固定 3.使用一块连续的内存来存储 各种操作的时间复杂度&#xff1a; 查找/修改&#xff1a;O&#xff08;1&#xff09;//访问特定位置的元素 插入…

[鹏城杯 2022]简单的php

题目源代码 <?phpshow_source(__FILE__); $code $_GET[code]; if(strlen($code) > 80 or preg_match(/[A-Za-z0-9]|\|"||\ |,|\.|-|\||\/|\\|<|>|\$|\?|\^|&|\|/is,$code)){die( Hello); }else if(; preg_replace(/[^\s\(\)]?\((?R)?\)/, , $code…

Qt实现tcp协议

void Widget::readyRead_slot() {//读取服务器发来的数据QByteArray msg socket->readAll();QString str QString::fromLocal8Bit(msg);QStringList list str.split(:);if(list.at(0) userName){QString str2;for (int i 1; i < list.count(); i) {str2 list.at(i);…

使用DOM破坏启动xss

目录 实验环境&#xff1a; 分析&#xff1a; 找破坏点&#xff1a; 查看源码找函数&#xff1a; 找到了三个方法&#xff0c;loadComments、escapeHTM 、displayComments loadComments escapeHTM displayComments&#xff1a; GOGOGO 实验环境&#xff1a; Lab: Exp…

JLMSR超分算法说明和效果

一、简介 JLMSR是基于加权概率模型构造的一种超分算法&#xff0c;属于传统超分&#xff0c;无需训练&#xff0c;适合硬件化。与传统超分的插值方案最大区别在于基于16*16的块进行上下文概率统计&#xff0c;结合权重进行插值。目前该插值方案已经线性化和整数化&#xff0c;…