【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();

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于windows的docker-desktop安装kubenetes以及dashboard

我们需要k8s环境做各种小实验可以本地安装一个&#xff0c;这里介绍win11如何通过docker-desktop安装k8s以及通过helm安装dashboard。 下载docker-desktop地址https://www.docker.com/get-started/打开【控制面板】->打开【启用和关闭windows功能】->分别勾选【hyper-v】…

Vue2是如何利用Object.defineProperty实现数据的双向绑定?

我们之前说道过Object.defineProperty方法有一关键特性&#xff0c;就是数据劫持&#xff0c;通过get/set 拦截属性的读取和修改操作。Vue主要是通过数据劫持结合发布-订阅模式来实现的&#xff0c;利用Object.defineProperty来劫持各个属性的setter和getter&#xff0c;在数据…

【Linux网络】认识协议(TCP/UDP)、Mac/IP地址和端口号、网络字节序、socket套接字

⭐️个人主页&#xff1a;小羊 ⭐️所属专栏&#xff1a;Linux 很荣幸您能阅读我的文章&#xff0c;诚请评论指点&#xff0c;欢迎欢迎 ~ 目录 1、初识协议2、UDP、TCP3、Mac、IP地址4、端口号5、网络字节序6、socket 1、初识协议 协议就是一种约定。如何让不同厂商生产的计…

基于flask+vue框架的的医院预约挂号系统i1616(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。

系统程序文件列表 项目功能:用户,医生,科室信息,就诊信息,医院概况,挂号信息,诊断信息,取消挂号 开题报告内容 基于FlaskVue框架的医院预约挂号系统开题报告 一、研究背景与意义 随着医疗技术的不断进步和人们健康意识的日益增强&#xff0c;医院就诊量逐年增加。传统的现场…

影刀RPA中级证书-Excel进阶-开票清单

1.操作题需求 请参照视频内容&#xff0c;将开票账单表格中的数据整理成开票清单。请下载 开票账单.xlsx 整理规则如下&#xff1a; 1. 金额为0的数据为赠品&#xff0c;无需开票&#xff0c;需删除2. 开票清单需要从开票账单中获取的数据包括有开票名称、数量、金额、税率&…

浅谈模组-相机鬼像

一&#xff0e;前言 在成像中&#xff0c;我们常常会遇到肉眼观测的真实世界中&#xff0c;不存在的异常光影出现在画面中&#xff0c;并伴有各种颜色&#xff0c;我们将这个物体称为鬼像。某些鬼像可能会对图像产生美感的体验&#xff0c;但是大多数的鬼像都会对图像的质量以…

Python爬虫实战:爬取豆瓣电影

目录 引言 1. 爬虫基础 1.1 什么是爬虫&#xff1f; 1.2 Python爬虫常用库 2. 实战&#xff1a;抓取豆瓣电影Top250 2.1 安装依赖库 2.2 发送HTTP请求 ​编辑 2.3 解析HTML ​编辑 2.4 存储数据 2.5 完整代码 3. 进阶&#xff1a;处理分页和动态内容 3.1 抓取多页…

Redis7——基础篇(六)

前言&#xff1a;此篇文章系本人学习过程中记录下来的笔记&#xff0c;里面难免会有不少欠缺的地方&#xff0c;诚心期待大家多多给予指教。 基础篇&#xff1a; Redis&#xff08;一&#xff09;Redis&#xff08;二&#xff09;Redis&#xff08;三&#xff09;Redis&#x…

Windows 下 Ollama 安装deepseek本地模型

Windows 下 Ollama 安装deepseek本地模型 安装 Ollama 下载 Ollama 下载链接&#xff1a;https://ollama.org.cn/download/windows 下载完成后&#xff0c;按照提示进行安装。 安装过程 安装完成后&#xff0c;安装页面会自动关闭&#xff0c;这是正常现象。 接下来&#…

【鸿蒙开发】第四十三章 Notification Kit(用户通知服务)

目录​​​​​​​ 1 简介 1.1 使用场景 1.2 能力范围 1.3 业务流程 1.4 通知样式 1.5 约束限制 1.6 与相关Kit的关系 2 请求通知授权 2.1 接口说明 2.2 开发步骤 3 管理通知角标 3.1 接口说明 3.2 开发步骤 4 管理通知渠道 4.1 通知渠道类型说明 4.2 接口说明…

bboss v7.3.5来袭!新增异地灾备机制和Kerberos认证机制,助力企业数据安全

ETL & 流批一体化框架 bboss v7.3.5 发布&#xff0c;多源输出插件增加为特定输出插件设置记录过滤功能&#xff1b;Elasticsearch 客户端新增异地双中心灾备机制&#xff0c;提升框架高可用性&#xff1b;Elasticsearch client 和 http 微服务框架增加对 Kerberos 认证支持…

利用非球面透镜进行激光光束重组

这是高斯分布激光束重塑透镜设计的分步演示。该透镜用于将高斯分布转换为成像平面上的均匀照明。 输入激光光束轮廓&#xff1a; 光学结构&#xff1a; Excel 中坐标的数学计算&#xff1a; 输出照度曲线&#xff1a;

(一)趣学设计模式 之 单例模式!

目录 一、啥是单例模式&#xff1f;二、为什么要用单例模式&#xff1f;三、单例模式怎么实现&#xff1f;1. 饿汉式&#xff1a;先下手为强&#xff01; &#x1f608;2. 懒汉式&#xff1a;用的时候再创建&#xff01; &#x1f634;3. 枚举&#xff1a;最简单最安全的单例&a…

nacos编写瀚高数据库插件

1、下载nacos源码 git clone gitgithub.com:alibaba/nacos.git 2、引入瀚高驱动 <dependency><groupId>com.highgo</groupId><artifactId>jdbc</artifactId><version>${highgo.version}</version></dependency> 3、DataSource…

讯飞唤醒+VOSK语音识别+DEEPSEEK大模型+讯飞离线合成实现纯离线大模型智能语音问答。

在信息爆炸的时代&#xff0c;智能语音问答系统正以前所未有的速度融入我们的日常生活。然而&#xff0c;随着数据泄露事件的频发&#xff0c;用户对于隐私保护的需求日益增强。想象一下&#xff0c;一个无需联网、即可响应你所有问题的智能助手——这就是纯离线大模型智能语音…

后端Java Stream数据流的使用=>代替for循环

API讲解 对比 示例代码对比 for循环遍历 package cn.ryanfan.platformback.service.impl;import cn.ryanfan.platformback.entity.Algorithm; import cn.ryanfan.platformback.entity.AlgorithmCategory; import cn.ryanfan.platformback.entity.DTO.AlgorithmInfoDTO; im…

UE 播放视频

一.UI播放视频 1.导入视频文件至工程文件夹 2.文件夹内右健选择Media -> File Meida Source创建testFileMeidaSource文件。 编辑FilePath为当前视频 3.右键->Media->Media Player 创建testMediaPlayer文件 4.右键创建testMediaTexture。编辑MediaPlayer设置testMedia…

推荐一款AI大模型托管平台-OpenWebUI

推荐一款AI大模型托管平台-OpenWebUI 1. OpenWebUI 1. OpenWebUI什么? 官网地址&#xff1a;https://openwebui.com/ GitHub地址&#xff1a; https://github.com/open-webui/open-webui Open WebUI 是一个可扩展、功能丰富且用户友好的自托管 AI 平台&#xff0c;旨在完全离…

【Python项目】基于知识图谱的百科问答系统

【Python项目】基于知识图谱的百科问答系统 技术简介&#xff1a; 采用Python技术、MySQL数据库、Django框架、Scrapy爬虫等技术实现。 系统简介&#xff1a; 百科问答系统是一个基于知识图谱的问答平台&#xff0c;旨在为用户提供快速、准确的百科知识查询服务。系统通过爬…

stm32rtc实时时钟详解文章

目录 stm32 后备区域基础知识详解 stm32 bkp基础知识详解 Unix时间戳基础知识详解 stm32 rtc实时时钟基础知识详解 相关代码初始化配置 欢迎指正&#xff0c;希望对你&#xff0c;有所帮助&#xff01;&#xff01;&#xff01; stm32 后备区域基础知识详解 stm32芯片的 …