【JavaWeb学习Day17】
Tlias智能学习系统(员工管理)
新增员工:
三层架构职责:
Controller:1.接收请求参数(员工信息);2.调用service方法;3.响应结果。
具体实现:
/***新增员工*/
@PostMapping
public Result save(@RequestBody Emp emp){log.info("新增员工:{}",emp);empService.save(emp);return Result.success();
}
Service:1.保存员工基本信息;2.批量保存员工的工作经历信息。
具体实现:
@Overridepublic void save(Emp emp) {//1.保存员工的基本信息emp.setCreateTime(LocalDateTime.now());emp.setUpdateTime(LocalDateTime.now());empMapper.insert(emp);
//2.保存员工的工作经历信息List<EmpExpr> exprList = emp.getExprList();if(!CollectionUtils.isEmpty(exprList)){//遍历集合,为empId赋值exprList.forEach(empExpr -> {empExpr.setEmpId(emp.getId());});empExprMapper.insertBatch(exprList);//Batch批量保存}}
Mapper:
-- 新增员工
-- 保存员工基本信息 emp
insert into emp(username, name, gender, phone, job, salary, image, entry_date, dept_id, create_time, update_time)values ('linpingzhi','林平之',1,'13309091234',1,600,'1.jpg','2020-01-01',1,'2024-10-01 00:00:00','2024-10-01 00:00:00');
-- 保存员工工作经历信息 emp_expr
insert into emp_expr(emp_id, begin, end, company, job)values (37,'2020-01-01','2021-01-01','百度','java开发'),(37,'2021-01-01','2022-01-01','字节','java开发');
具体实现:
EmpMapper:
/*** 新增员工基本信息* @param emp*/@Options(useGeneratedKeys = true,keyProperty = "id") //获取到生成的主键 -- 主键返回@Insert("insert into emp(username, name, gender, phone, job, salary, image, entry_date, dept_id, create_time, update_time)" +" values (#{username},#{name},#{gender},#{phone},#{job},#{salary},#{image},#{entryDate},#{deptId},#{createTime},#{updateTime})")void insert(Emp emp);
EmpExprMapper:
/*** 批量插入员工工作经历信息*/
void insertBatch(List<EmpExpr> exprList);
批量插入员工的工作经历用到配置文件(动态SQL):
EmpExprMapper.xml:
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.itheima.mapper.EmpExprMapper">
<!-- 批量保存员工工作经历--><insert id="insertBatch">insert into emp_expr(emp_id, begin, end, company, job) values<foreach collection="exprList" item="expr" separator=",">(#{expr.empId},#{expr.begin},#{expr.end},#{expr.company},#{expr.job})</foreach></insert>
</mapper>
动态SQL:<foreach>属性说明:
1.collection:集合名称
2.item:集合遍历出来的元素/项
3.separator:每一次遍历使用的分隔符
4.open:遍历开始前拼接的片段
5.close:遍历结束后拼接的片段
事务管理:
问:保存员工的基本信息成功了,而保存工作经历失败了,是否OK?
答:不可以,因为这是属于一个业务操作,如果保存员工信息成功了,保存工作经历信息失败了,就会造成数据库数据的不完整、不一致。
介绍&操作:
概念:事务是一组操作的集合,它是一个不可分割的工作单位。事务会把所有的操作作为一个整体一起向系统提交或撤销操作请求,即这些操作,要么同时成功,要么同时失败。
(注意:默认MySQL的事务是自动提交的,也就是说,当执行一条DML语句,MySQL会立即隐式的提交事务。)
操作:事务控制主要三步操作:开启事务、提交事务/回滚事务。
-- 开启事务
start transaction; / begin;
-- 1. 保存员工基本信息
insert into emp values (39, 'Tom', '123456', '汤姆', 1, '13300001111', 1, 4000, '1.jpg', '2023-11-01', 1, now(), now());
-- 2. 保存员工的工作经历信息
insert into emp_expr(emp_id, begin, end, company, job) values (39,'2019-01-01', '2020-01-01', '百度', '开发'), (39,'2020-01-10', '2022-02-01', '阿里', '架构');
-- 提交事务(全部成功)
commit;
-- 回滚事务(有一个失败)
rollback;
Spring事务管理:
注解:@Transactional
作用:将当前方法交给spring进行事务管理,方法执行前,开启事务;成功执行完毕,提交事务;出现异常,回滚事务
位置:业务(service)层的方法上、类上、接口上(推荐使用在方法上)
@Transactional //事务管理 - 默认出现运行时异常RunTimeException才会回滚
@Override
public void save(Emp emp) {//1.保存员工的基本信息emp.setCreateTime(LocalDateTime.now());emp.setUpdateTime(LocalDateTime.now());empMapper.insert(emp);
//2.保存员工的工作经历信息List<EmpExpr> exprList = emp.getExprList();if(!CollectionUtils.isEmpty(exprList)){//遍历集合,为empId赋值exprList.forEach(empExpr -> {empExpr.setEmpId(emp.getId());});empExprMapper.insertBatch(exprList);//Batch批量保存}
}
事务进阶:
1.rollbackFor属性用于控制出现何种异常类型,回滚事务。
@Transactional(rollbackFor = {Exception.class}) //事务管理 所有异常都回滚
2.事务传播行为(propagation):指的是当一个事务方法被另一个事务方法调用时,这个事务方法应该如何进行事务控制。
@Transactional(propagation = Propagation.REQUIRED)

案例:新增员工信息,记录日志(propagation)
需求:在新增员工信息时,无论是成功还是失败,都要记录操作日志。
步骤:1.准备日志表emp_log、实体类Emplog、Mapper接口EmpLogMapper;2.在新增员工时记录日志
@Transactional(rollbackFor = {Exception.class}) //事务管理 - 默认出现运行时异常RunTimeException才会回滚
@Override
public void save(Emp emp) {try{//1.保存员工的基本信息emp.setCreateTime(LocalDateTime.now());emp.setUpdateTime(LocalDateTime.now());empMapper.insert(emp);
//2.保存员工的工作经历信息List<EmpExpr> exprList = emp.getExprList();if(!CollectionUtils.isEmpty(exprList)){//遍历集合,为empId赋值exprList.forEach(empExpr -> {empExpr.setEmpId(emp.getId());});empExprMapper.insertBatch(exprList);//Batch批量保存}
}finally {//记录操作日志EmpLog empLog = new EmpLog(null,LocalDateTime.now(),"新增员工"+emp);empLogService.insertLog(empLog);
}
}
@Service
public class EmpLogServiceImpl implements EmpLogService {
@Autowiredprivate EmpLogMapper empLogMapper;@Transactional(propagation = Propagation.REQUIRES_NEW)@Overridepublic void insertLog(EmpLog empLog) {empLogMapper.insert(empLog);}
}
四大特性(ACID):
原子性Atomicity:事务是不可分割的最小单元,要么全部成功,要么全部失败
一致性Consistency:事务完成时,必须使所有的数据都保持一致状态
隔离性Isolation:数据库系统提供的隔离机制,保证事务在不受外部并发操作影响的独立环境下运行
持久性Durability:事务一旦提交或回滚,他对数据库中的数据的改变就是永久的
文件上传:
简介:
文件上传:是指将本地的图片、视频、音频等文件上传到服务器,供其他用户浏览或者下载的过程。
文件上传在项目中应用非常广泛,我们经常发微博、发微信朋友圈都用到了文件上传功能。

本地存储:
@Slf4j
@RestController
public class UploadController {@PostMapping("/upload")public Result upload(String name, Integer age, MultipartFile file) throws IOException {log.info("接收到的参数:{},{},{}",name,age,file);//获取原始文件名String originalFileName = file.getOriginalFilename();
//新的文件名String extension = originalFileName.substring(originalFileName.lastIndexOf("."));String newFileName = UUID.randomUUID().toString() + extension;
//保存文件file.transferTo(new File("D:\\xxzl\\java\\file\\"+originalFileName));return Result.success();}
}
(注意:上传文件大小受限去设置yml文件)
spring:servlet:multipart:#最大单个文件大小max-file-size: 10MB#最大请求大小(包括所有文件和表单数据)max-request-size: 100MB
阿里云OSS:
阿里云:阿里云是阿里巴巴集团旗下全球领先的云计算公司,也是全球最大的云服务提供商。
阿里云OSS:阿里云对象存储OSS(Object Storage Service),是一款海量、安全、低成本、高可靠的云储存服务。使用OSS,您可以通过网络随时存储和调用包括文本、图片、音频和视频等在内的各种文件。
第三方服务-通用思路:准备工作->参照官方SDK编写入门程序->集成使用
(SDK:Software Development Kit的缩写,软件开发工具包,包括辅助软件开发的依赖(jar包),示例代码等,都可以叫SDK)
阿里云OSS—使用步骤:
准备工作:注册阿里云(实名认证)->充值->开通对象存储服务OSS->创建bucket->获取并配置AccessKey(密钥)
(Bucket:存储空间是用户用于存储对象(Object,就是文件)的容器,所有的对象都必须隶属于某个存储空间)
入门程序:
package com.itheima;
import com.aliyun.oss.*;
import com.aliyun.oss.common.auth.CredentialsProviderFactory;
import com.aliyun.oss.common.auth.EnvironmentVariableCredentialsProvider;
import com.aliyun.oss.common.comm.SignVersion;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.nio.file.Files;
public class Demo {
public static void main(String[] args) throws Exception {// Endpoint以华东1(杭州)为例,其它Region请按实际情况填写。String endpoint = "https://oss-cn-beijing.aliyuncs.com";// 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();// 填写Bucket名称,例如examplebucket。String bucketName = "java-ai";// 填写Object完整路径,例如exampledir/exampleobject.txt。Object完整路径中不能包含Bucket名称。String objectName = "001.jpg";// 填写Bucket所在地域。以华东1(杭州)为例,Region填写为cn-hangzhou。String region = "cn-beijing";
// 创建OSSClient实例。ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);OSS ossClient = OSSClientBuilder.create().endpoint(endpoint).credentialsProvider(credentialsProvider).clientConfiguration(clientBuilderConfiguration).region(region).build();
try {File file = new File("C:\\Users\\deng\\Pictures\\1.jpg");byte[] content = Files.readAllBytes(file.toPath());
ossClient.putObject(bucketName, objectName, new ByteArrayInputStream(content));} 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-案例集成:

1.引入阿里云OSS文件上传工具类(由官方的示例代码改造而来)
package com.itheima.utils;
import com.aliyun.oss.*;
import com.aliyun.oss.common.auth.CredentialsProviderFactory;
import com.aliyun.oss.common.auth.EnvironmentVariableCredentialsProvider;
import com.aliyun.oss.common.comm.SignVersion;
import org.springframework.stereotype.Component;
import java.io.ByteArrayInputStream;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.UUID;
@Component
public class AliyunOSSOperator {
private String endpoint = "https://oss-cn-beijing.aliyuncs.com";private String bucketName = "java-ai-0770";private String region = "cn-beijing";
public String upload(byte[] content, String originalFilename) throws Exception {// 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
// 填写Object完整路径,例如202406/1.png。Object完整路径中不能包含Bucket名称。//获取当前系统日期的字符串,格式为 yyyy/MMString dir = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy/MM"));//生成一个新的不重复的文件名String newFileName = UUID.randomUUID() + originalFilename.substring(originalFilename.lastIndexOf("."));String objectName = dir + "/" + newFileName;
// 创建OSSClient实例。ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);OSS ossClient = OSSClientBuilder.create().endpoint(endpoint).credentialsProvider(credentialsProvider).clientConfiguration(clientBuilderConfiguration).region(region).build();
try {ossClient.putObject(bucketName, objectName, new ByteArrayInputStream(content));} finally {ossClient.shutdown();}
return endpoint.split("//")[0] + "//" + bucketName + "." + endpoint.split("//")[1] + "/" + objectName;}
}
2.上传文件接口开发
@Autowired
private AliyunOSSOperator aliyunOSSOperator;
@PostMapping("/upload")
public Result upload(MultipartFile file) throws Exception {log.info("文件上传:{}",file.getOriginalFilename());//将文件交给OSS存储管理String url = aliyunOSSOperator.upload(file.getBytes(), file.getOriginalFilename());log.info("文件上传OSS,url:{}",url);return Result.success(url);
}
参数配置化:
指将一些需要灵活变化得参数,配置在配置文件中,然后通过@Value注解来注入外部配置得属性。
#阿里云OSS
aliyun:oss:endpoint: https://oss-cn-beijing.aliyuncs.combucketName: java-ai-0770region: cn-beijing
@Value("${aliyun.oss.endpoint}")
private String endpoint ;
@Value("${aliyun.oss.bucketName}")
private String bucketName ;
@Value("${aliyun.oss.region}")
private String region ;
使用@Value注解注入配置文件得配置项,如果配置项多,注入繁琐,不便于维护管理和复用。使用@ConfigurationProperties
@Data
@Component
@ConfigurationProperties(prefix = "aliyun.oss")
public class AliyunOSSProperties {private String endpoint;private String bucketName;private String region;
}
@Autowired
private AliyunOSSProperties aliyunOSSProperties;String endpoint = aliyunOSSProperties.getEndpoint();String bucketName = aliyunOSSProperties.getBucketName();String region = aliyunOSSProperties.getRegion();
相关文章:
【JavaWeb学习Day17】
Tlias智能学习系统(员工管理) 新增员工: 三层架构职责: Controller:1.接收请求参数(员工信息);2.调用service方法;3.响应结果。 具体实现: /***新增员工…...
DeepSeek 提示词:定义、作用、分类与设计原则
🧑 博主简介:CSDN博客专家,历代文学网(PC端可以访问:https://literature.sinhy.com/#/?__c1000,移动端可微信小程序搜索“历代文学”)总架构师,15年工作经验,精通Java编…...
前端大文件上传
1. 开场概述 “大文件上传是前端开发中常见的需求,但由于文件体积较大,直接上传可能会遇到网络不稳定、服务器限制等问题。因此,通常需要采用分片上传、断点续传、并发控制等技术来优化上传体验” 2. 核心实现方案 “我通常会采用以下方案…...
JDK源码系列(一)Object
Object 概述 Object类是所有类的基类——java.lang.Object。 Object类是所有类的基类,当一个类没有直接继承某个类时,默认继承Object类Object类属于java.lang包下,此包下的所有类在使用时无需手动导入,系统会在程序编译期间自动…...
【Python 打造高效文件分类工具】
【Python】 打造高效文件分类工具 一、代码整体结构二、关键代码解析(一)初始化部分(二)界面创建部分(三)核心功能部分(四)其他辅助功能部分 三、运行与使用四、示图五、作者有话说 …...
大数据组件(四)快速入门实时数据湖存储系统Apache Paimon(1)
Paimon的下载及安装,并且了解了主键表的引擎以及changelog-producer的含义参考: 大数据组件(四)快速入门实时数据湖存储系统Apache Paimon(1) 利用Paimon表做lookup join,集成mysql cdc等参考: 大数据组件(四)快速入门实时数据…...
边缘安全加速(Edge Security Acceleration)
边缘安全加速(Edge Security Acceleration,简称ESA)是一种通过将安全功能与网络边缘紧密结合来提升安全性和加速网络流量的技术。ESA的目标是将安全措施部署到接近用户或设备的地方,通常是在网络的边缘,而不是将所有流…...
C/C++高性能Web开发框架全解析:2025技术选型指南
一、工业级框架深度解析(附性能实测) 1. Drogon v2.1:异步框架性能王者 核心架构: Reactor 非阻塞I/O线程池(参考Nginx模型) 协程实现:基于Boost.Coroutine2(兼容C11)…...
fedora 安装 ffmpeg 过程记录
参考博客:1. linux(centos)安装 ffmpeg,并添加 libx264库:https://blog.csdn.net/u013015301/article/details/140778199ffmpeg 执行时如添加参数 -vcodec libx264,会出现错误:Unknown encoder libx264’的错误,缺少li…...
【GPU驱动】OpenGLES图形管线渲染机制
OpenGLES图形管线渲染机制 OpenGL/ES 的渲染管线也是一个典型的图形流水线(Graphics Pipeline),包括多个阶段,每个阶段都负责对图形数据进行处理。管线的核心目标是将图形数据转换为最终的图像,这些图像可以显示在屏幕…...
Spring Boot项目@Cacheable注解的使用
Cacheable 是 Spring 框架中用于缓存的注解之一,它可以帮助你轻松地将方法的结果缓存起来,从而提高应用的性能。下面详细介绍如何使用 Cacheable 注解以及相关的配置和注意事项。 1. 基本用法 1.1 添加依赖 首先,确保你的项目中包含了 Spr…...
mac开发环境配置笔记
1. 终端配置 参考: Mac终端配置笔记-CSDN博客 2. 下载JDK 到 oracle官网 下载jdk: oracle官网 :Java Downloads | Oraclemac的芯片为Intel系列下载 x64版本的jdk;为Apple Mx系列使用 Arm64版本;oracle官网下载时报错:400 Bad R…...
重装CentOS YUM
1. 检查是否已安装 YUM 运行以下命令检查 YUM 是否已安装: yum list installed | grep yum 如果输出中包含 yum,则说明 YUM 已安装。 2. 卸载旧版本的 YUM(如有必要) 如果需要重新安装 YUM,可以先卸载旧版本&…...
对免认证服务提供apikey验证
一些服务不带认证,凡是可以访问到服务端口,都可以正常使用该服务,方便是方便,但是不够安全。 比如ollama默认安装后就是这样。现在据说网上扫一下端口11434,免apikey的ollama服务一大堆。。。 那我们怎样将本机安装的o…...
数据库驱动免费下载(Oracle、Mysql、达梦、Postgresql)
数据库驱动找起来好麻烦,我整理到了一起,需要的朋友免费下载:驱动下载 目前收录了Oracle、Mysql、达梦、Postgresql的数据库驱动的多个版本,后续可能会分享更多。...
OceanBase 初探学习历程之——安装部署
一、介绍 OceanBase 数据库是一个原生的分布式关系数据库,它是完全由阿里巴巴和蚂蚁集团自主研发 的项目。OceanBase 数据库构建在通用服务器集群上,基于 Paxos 协议和分布式架构,提供 金融级高可用和线性伸缩能力,不依赖特定硬件…...
Windows 下免费开源的多格式文件差异对比工具
软件介绍 有这样一款诞生于 2000 年、专为 Windows 系统打造的开源免费工具,截至 2025 年 1 月已更新至 2.16.46 版本,它就是文件与文件夹比较的得力助手。 其支持文本文件、Word、Excel、PPT 网页、图像等多种格式对比,利用高亮显示行内差…...
Vue3+element UI:使用el-dialog时,对话框不出现解决方案
解决方案:在<el-dialog>标签中,添加:append-to-body“true”*,对话框即可弹出。*...
postman调用ollama的api
按照如下设置,不需要设置key 保持长会话的方法 # 首次请求 curl http://localhost:11434/api/generate -d {"model": "deepseek-r1:32b","prompt": "请永久记住:110,1-12,之后所有数学计算必…...
PyTorch的dataloader制作自定义数据集
PyTorch的dataloader是用于读取训练数据的工具,它可以自动将数据分割成小batch,并在训练过程中进行数据预处理。以下是制作PyTorch的dataloader的简单步骤: 导入必要的库 import torch from torch.utils.data import DataLoader, Dataset定…...
利用ngx_stream_return_module构建简易 TCP/UDP 响应网关
一、模块概述 ngx_stream_return_module 提供了一个极简的指令: return <value>;在收到客户端连接后,立即将 <value> 写回并关闭连接。<value> 支持内嵌文本和内置变量(如 $time_iso8601、$remote_addr 等)&a…...
Day131 | 灵神 | 回溯算法 | 子集型 子集
Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣(LeetCode) 思路: 笔者写过很多次这道题了,不想写题解了,大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...
【网络安全产品大调研系列】2. 体验漏洞扫描
前言 2023 年漏洞扫描服务市场规模预计为 3.06(十亿美元)。漏洞扫描服务市场行业预计将从 2024 年的 3.48(十亿美元)增长到 2032 年的 9.54(十亿美元)。预测期内漏洞扫描服务市场 CAGR(增长率&…...
Linux相关概念和易错知识点(42)(TCP的连接管理、可靠性、面临复杂网络的处理)
目录 1.TCP的连接管理机制(1)三次握手①握手过程②对握手过程的理解 (2)四次挥手(3)握手和挥手的触发(4)状态切换①挥手过程中状态的切换②握手过程中状态的切换 2.TCP的可靠性&…...
最新SpringBoot+SpringCloud+Nacos微服务框架分享
文章目录 前言一、服务规划二、架构核心1.cloud的pom2.gateway的异常handler3.gateway的filter4、admin的pom5、admin的登录核心 三、code-helper分享总结 前言 最近有个活蛮赶的,根据Excel列的需求预估的工时直接打骨折,不要问我为什么,主要…...
使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装
以下是基于 vant-ui(适配 Vue2 版本 )实现截图中照片上传预览、删除功能,并封装成可复用组件的完整代码,包含样式和逻辑实现,可直接在 Vue2 项目中使用: 1. 封装的图片上传组件 ImageUploader.vue <te…...
mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包
文章目录 现象:mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包遇到 rpm 命令找不到已经安装的 MySQL 包时,可能是因为以下几个原因:1.MySQL 不是通过 RPM 包安装的2.RPM 数据库损坏3.使用了不同的包名或路径4.使用其他包…...
蓝桥杯 冶炼金属
原题目链接 🔧 冶炼金属转换率推测题解 📜 原题描述 小蓝有一个神奇的炉子用于将普通金属 O O O 冶炼成为一种特殊金属 X X X。这个炉子有一个属性叫转换率 V V V,是一个正整数,表示每 V V V 个普通金属 O O O 可以冶炼出 …...
Python基于历史模拟方法实现投资组合风险管理的VaR与ES模型项目实战
说明:这是一个机器学习实战项目(附带数据代码文档),如需数据代码文档可以直接到文章最后关注获取。 1.项目背景 在金融市场日益复杂和波动加剧的背景下,风险管理成为金融机构和个人投资者关注的核心议题之一。VaR&…...
认识CMake并使用CMake构建自己的第一个项目
1.CMake的作用和优势 跨平台支持:CMake支持多种操作系统和编译器,使用同一份构建配置可以在不同的环境中使用 简化配置:通过CMakeLists.txt文件,用户可以定义项目结构、依赖项、编译选项等,无需手动编写复杂的构建脚本…...
