Web day08 项目实战(2)
目录
查询员工:
接口文档为:
因为请求参数过多 所以 把传入的请求参数封装为对象
返回 data中需要有 total 和 rows属性所以 需要 单独定义实体类:PageResult、
分页查询的对象都要 封装 在PageResult中 注释掉的count为查询总数
因为传入的数据为 传统url风格 所以 只要传入的 字段名 和实体类中的 变量名相同即可 自动传入
只有 在传入的数据为 json 对象 时 (例如post请求的请求体为json对象)接json的对象 时 才用
@RequestBody 修饰 参数
在EmpController层:
直接用对象名接收即可 不用写@RequestBody
在pojo层:
在EmpServiceImpl 层中:
运用PageHelper 中 的 getTotal可获得总数 getResult 可以根据 传入的 page 和PageSize
得到指定页的全部数据
pageHelper的依赖为:
<!-- 分页插件PageHelper -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.4.7</version>
</dependency>
PageHelper.startPage(从第几页开始,一共分多少页)
利用动态代理和插入的思想 可以 省略 分页查询 在后续Service层调用 dao层时 查询时 不用传入 分页查询的参数
分页查询:
在dao层:
利用xml 映射文件 写出 sql 查询语句 因为 不能把sql写死 要根据 参数是否 为空进行 条件判断:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.itheima.dao.EmpMapper">
<!--查询操作-->
<select id="list" resultType="com.itheima.pojo.Emp">
select * from emp e left join dept d on e.dept_id = d.id
<where>
<if test="name!=null and name!=''">
and e.name like concat('%',#{name},'%')
</if>
<if test="gender!=null">
and e.gender = #{gender}
</if>
<if test="begin!=null and begin!=''">
and e.entry_date >= #{begin}
</if>
<if test="end!=null and end!=''">
and e.entry_date <= #{end}
</if>
</where>
</select>
<insert id="insertExprBatch">
insert into emp_expr(emp_id,begin,end,company,job) values
<foreach collection="list" item="expr" separator=",">
(#{expr.empId},#{expr.begin},#{expr.end},#{expr.company},#{expr.job})
</foreach>
</insert>
</mapper>
新增员工:
发送请求的格式
pojo层:
1). 需要在 Emp
员工实体类中增加属性 exprList
来封装工作经历数据。 最终完整代码如下:
@Data
public class Emp {
private Integer id; //ID,主键
private String username; //用户名
private String password; //密码
private String name; //姓名
private Integer gender; //性别, 1:男, 2:女
private String phone; //手机号
private Integer job; //职位, 1:班主任,2:讲师,3:学工主管,4:教研主管,5:咨询师
private Integer salary; //薪资
private String image; //头像
private LocalDate entryDate; //入职日期
private Integer deptId; //关联的部门ID
private LocalDateTime createTime; //创建时间
private LocalDateTime updateTime; //修改时间
//封装部门名称数
private String deptName; //部门名称
//封装员工工作经历信息
private List<EmpExpr> exprList;
}
EmpController层:
在EmpServiceImpl 层中:
在EmpMapper层:
主键返回:
主键返回:@Options(useGeneratedKeys = true, keyProperty = "id")
由于稍后,我们在保存工作经历信息的时候,需要记录是哪位员工的工作经历。 所以,保存完员工信息之后,是需要获取到员工的ID的,那这里就需要通过Mybatis中提供的主键返回功能来获取。
useGeneratedKeys = true:
表示启用自动生成的主键值。
通常用于插入记录时,数据库会自动生成主键值(例如,使用 AUTO_INCREMENT 的 MySQL 表)。
keyProperty = "id":
指定将自动生成的主键值赋值给对象的哪个属性。
在这个例子中,自动生成的主键值会被赋值给对象的 id 属性。
在EmpExprMapper层中:
添加员工经历
在EmpExprMapper.xml 映射文件中写 sql 插入语句
主键为自增在 insert into emp_expr() 括号中不用写入 id
事务管理:
目的:
在添加 员工 时 添加员工数据 和 员工经历 要一起 添加成功 或 添加失败 防止因为经历添加失败 员工经历添加成功 会导致数据库数据 的不完整 不一致
Transactional注解:
可以在application.yml
配置文件中开启事务管理日志,这样就可以在控制看到和事务相关的日志信息了
#spring事务管理日志
logging:
level:
org.springframework.jdbc.support.JdbcTransactionManager: debug
rollbackFor:
Teansactional 默认为RuntimeException 只能改成 范围大的 Exeption 遇到所有异常都会 回滚事务
propagation:
@Transactional注解当中的第二个属性propagation,这个属性是用来配置事务的传播行为的。
在日志记录中运用 propagation 属性 使日志记录 保存到数据库中成为 单独的事务 不受 添加员工 和 添加 员工经历数据 的事务影响
其他属性:
事务的四大特性(面试):
-
原子性(Atomicity):事务是不可分割的最小单元,要么全部成功,要么全部失败。
-
一致性(Consistency):事务完成时,必须使所有的数据都保持一致状态。
-
隔离性(Isolation):数据库系统提供的隔离机制,保证事务在不受外部并发操作影响的独立环境下运行。
-
持久性(Durability):事务一旦提交或回滚,它对数据库中的数据的改变就是永久的。
文件上传:
生成的前端代码形式如下:
<!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="file"><br>
<input type="submit" value="提交">
</form>
</body>
</html>
上传文件页面三要素:
-
表单必须有file域,用于选择要上传的文件
-
表单提交方式必须为POST:通常上传的文件会比较大,所以需要使用 POST 提交方式
-
表单的编码类型enctype必须要设置为:multipart/form-data:普通默认的编码格式是不适合传输大型的二进制数据的,所以在文件上传时,表单的编码格式必须设置为multipart/form-data
服务端代码为:
@RestController
public class UpLoadFileController {
@PostMapping("/upload2")
public Result upload(String name , Integer age , MultipartFile file) throws Exception {
String originalFilename = file.getOriginalFilename();
//生成新的文件名 用重复的文件名可能被覆盖并取原文件后缀名
String newFileName = UUID.randomUUID().toString() + originalFilename.substring(originalFilename.lastIndexOf("."));
File dir = new File("D:/resource/images/");
if (!dir.exists()){
dir.mkdirs();
}
//transferTo 方法可以把文件写入磁盘
file.transferTo(new File(dir,newFileName));
return Result.Success("http://localhost:8080/images/"+newFileName);
}
}
工具类 单独建一个包 叫 uiti
引入阿里云实现 文件 上传:
接口信息:
响应数据格式为:
FileUploadController层:
用MultipartFile 类型接受 file对象:
file.getBytes() 为获取文件的字节码文件
工具类(上传文件到阿里云):
@Component
public class OSSFileUpholdUtil {
@Value(value = "${aliyun.oss.endpoint}")
private String endpoint ;
@Value(value = "${aliyun.oss.bucketName}")
private String bucketName ;
@Value(value = "${aliyun.oss.region}")
private String region ;
public String upload(String originalFilename,byte[] content) throws Exception {
// 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
// 填写Object完整路径,例如202406/1.png。Object完整路径中不能包含Bucket名称。
//获取当前系统日期的字符串,格式为 yyyy/MM
String 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));
System.out.println("文件 " + objectName + " 上传成功。");
} finally {
ossClient.shutdown();
}
return "https://" + bucketName + "." + endpoint.replaceAll("https://", "") + "/" + objectName;
}
}
application.yml中配置
aliyun:
oss:
endpoint: https://oss-cn-beijing.aliyuncs.com
bucketName: mos-strorge
region: cn-beijing
原文地址:https://blog.csdn.net/moskidi/article/details/144276692
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!