【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定…...
stm32G473的flash模式是单bank还是双bank?
今天突然有人stm32G473的flash模式是单bank还是双bank?由于时间太久,我真忘记了。搜搜发现,还真有人和我一样。见下面的链接:https://shequ.stmicroelectronics.cn/forum.php?modviewthread&tid644563 根据STM32G4系列参考手…...
Python:操作 Excel 折叠
💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...
【磁盘】每天掌握一个Linux命令 - iostat
目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat(I/O Statistics)是Linux系统下用于监视系统输入输出设备和CPU使…...
屋顶变身“发电站” ,中天合创屋面分布式光伏发电项目顺利并网!
5月28日,中天合创屋面分布式光伏发电项目顺利并网发电,该项目位于内蒙古自治区鄂尔多斯市乌审旗,项目利用中天合创聚乙烯、聚丙烯仓库屋面作为场地建设光伏电站,总装机容量为9.96MWp。 项目投运后,每年可节约标煤3670…...
如何将联系人从 iPhone 转移到 Android
从 iPhone 换到 Android 手机时,你可能需要保留重要的数据,例如通讯录。好在,将通讯录从 iPhone 转移到 Android 手机非常简单,你可以从本文中学习 6 种可靠的方法,确保随时保持连接,不错过任何信息。 第 1…...
九天毕昇深度学习平台 | 如何安装库?
pip install 库名 -i https://pypi.tuna.tsinghua.edu.cn/simple --user 举个例子: 报错 ModuleNotFoundError: No module named torch 那么我需要安装 torch pip install torch -i https://pypi.tuna.tsinghua.edu.cn/simple --user pip install 库名&#x…...
网站指纹识别
网站指纹识别 网站的最基本组成:服务器(操作系统)、中间件(web容器)、脚本语言、数据厍 为什么要了解这些?举个例子:发现了一个文件读取漏洞,我们需要读/etc/passwd,如…...
初探Service服务发现机制
1.Service简介 Service是将运行在一组Pod上的应用程序发布为网络服务的抽象方法。 主要功能:服务发现和负载均衡。 Service类型的包括ClusterIP类型、NodePort类型、LoadBalancer类型、ExternalName类型 2.Endpoints简介 Endpoints是一种Kubernetes资源…...
Razor编程中@Html的方法使用大全
文章目录 1. 基础HTML辅助方法1.1 Html.ActionLink()1.2 Html.RouteLink()1.3 Html.Display() / Html.DisplayFor()1.4 Html.Editor() / Html.EditorFor()1.5 Html.Label() / Html.LabelFor()1.6 Html.TextBox() / Html.TextBoxFor() 2. 表单相关辅助方法2.1 Html.BeginForm() …...
Bean 作用域有哪些?如何答出技术深度?
导语: Spring 面试绕不开 Bean 的作用域问题,这是面试官考察候选人对 Spring 框架理解深度的常见方式。本文将围绕“Spring 中的 Bean 作用域”展开,结合典型面试题及实战场景,帮你厘清重点,打破模板式回答,…...
