苍穹外卖项目---------收获以及改进(3-4天)

①公共字段填充----mybatis

第一步:自定义注解
/*** 自定义注解用于标识某个方法需要进行功能字段的填充*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AutoFill {//枚举:数据库操作类型: update insertOperationType value();
}

 枚举类:

/*** 数据库操作类型*/
public enum OperationType {/*** 更新操作*/UPDATE,/*** 插入操作*/INSERT}
第二步:自定义切面类
/*** 自定义切面,实现公共字段自动填充处理逻辑*/
@Aspect
@Component
@Slf4j
public class AutoFillAspect {/*** 切入点*///指定拦截哪些mapper类    拦截所有的mapper中的所有方法 && 方法上加入了自定义注解的方法@Pointcut("execution(* com.sky.service.*.*(..)) && @annotation(com.sky.annotation.AutoFill)")public void autoFillPointcut(){}//前置通知,在方法前为公共字段赋值@Before("autoFillPointcut()")//传来切入点public void autoFill(JoinPoint joinPoint){log.info("开始进行公共字段的填充");//获取到当前被拦截的方法上操作数据库的类型MethodSignature signature = (MethodSignature)joinPoint.getSignature();  //先获得方法对象AutoFill autofill = signature.getMethod().getAnnotation(AutoFill.class);//再获得方法上的注解对象OperationType operationtype = autofill.value();                         //最后获得数据库操作类型//获取到当前被拦截的方法上的参数Object[] args = joinPoint.getArgs();if(args == null || args.length == 0){return;}Object entity = args[0];//准备赋值的数据LocalDateTime now = LocalDateTime.now();Long currentId = BaseContext.getCurrentId();//为参数里的属性进行反射赋值if(operationtype == OperationType.INSERT){//为四个公共字段赋值try {//获得属性的set方法Method setCreatTime = entity.getClass().getDeclaredMethod("setCreatTime", LocalDateTime.class);Method setCreateUser = entity.getClass().getDeclaredMethod("setCreateUser", Long.class);Method setUpdateTime = entity.getClass().getDeclaredMethod("setUpdateTime", LocalDateTime.class);Method setUpdateUser = entity.getClass().getDeclaredMethod("setUpdateUser", Long.class);//反射赋值setCreatTime.invoke(entity,now);setCreateUser.invoke(entity,currentId);setUpdateTime.invoke(entity,now);setUpdateUser.invoke(entity,currentId);} catch (Exception e) {e.printStackTrace();}}else if (operationtype == OperationType.UPDATE){//为两个公共字段赋值try {//获得属性的set方法Method setUpdateTime = entity.getClass().getDeclaredMethod("setUpdateTime", LocalDateTime.class);Method setUpdateUser = entity.getClass().getDeclaredMethod("setUpdateUser", Long.class);//反射赋值setUpdateTime.invoke(entity,now);setUpdateUser.invoke(entity,currentId);} catch (Exception e) {e.printStackTrace();}}}
}
第三步:在mapper层的方法上加上我们的自定义注解以及类型

②公共字段填充----mybatisPlus

第一步:字段上添加注解
    @TableField(fill = FieldFill.INSERT)//插入时填充private LocalDateTime createTime;@TableField(fill = FieldFill.INSERT_UPDATE)//插入以及更新时填充private LocalDateTime updateTime;@TableField(fill = FieldFill.INSERT)//插入时填充private Long createUser;@TableField(fill = FieldFill.INSERT_UPDATE)//插入以及更新时填充private Long updateUser;
第二步:编写元数据处理类
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.sky.context.BaseContext;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;//元数据处理器
@Component
@Slf4j
public class MyMetaObjecthandler implements MetaObjectHandler    {@Overridepublic void insertFill(MetaObject metaObject) {log.info("公共字段自动填充---新增 :{}",metaObject);//设置数据metaObject.setValue("createTime",LocalDateTime.now());metaObject.setValue("createUser",BaseContext.getCurrentId());metaObject.setValue("updateTime", LocalDateTime.now());metaObject.setValue("updateUser", BaseContext.getCurrentId());}@Overridepublic void updateFill(MetaObject metaObject) {log.info("公共字段自动填充---更新 :{}",metaObject);//设置数据metaObject.setValue("updateTime", LocalDateTime.now());metaObject.setValue("updateUser", BaseContext.getCurrentId());}
}

 这样就可以实现mybatisPlus的公共字段填充,之后在写实体类的相关字段时就可以不用自己去set,用这个控制器去自动完成可以

③阿里云OSS----文件上传

前端上传:

后端接收:

后端进行文件存储-----存储在本地(transferTo):

后端进行文件存储-----存储在云(阿里云OSS,object storage service)

 

第一步:引入依赖
<dependency><groupId>com.aliyun.oss</groupId><artifactId>aliyun-sdk-oss</artifactId><version>3.15.1</version>
</dependency>//如果java 版本9以上则要添加以下依赖
<dependency><groupId>javax.xml.bind</groupId><artifactId>jaxb-api</artifactId><version>2.3.1</version>
</dependency>
<dependency><groupId>javax.activation</groupId><artifactId>activation</artifactId><version>1.1.1</version>
</dependency>
<!-- no more than 2.3.3-->
<dependency><groupId>org.glassfish.jaxb</groupId><artifactId>jaxb-runtime</artifactId><version>2.3.3</version>
</dependency>
第二步:改配置,存文件
        // Endpoint以华东1(杭州)为例,其它Region请按实际情况填写。String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";// 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();// 填写Bucket名称,例如examplebucket。String bucketName = "examplebucket";// 填写Object完整路径,完整路径中不能包含Bucket名称,例如exampledir/exampleobject.txt。String objectName = "exampledir/exampleobject.txt";// 填写本地文件的完整路径,例如D:\\localpath\\examplefile.txt。// 如果未指定本地路径,则默认从示例程序所属项目对应本地路径中上传文件流。String filePath= "D:\\localpath\\examplefile.txt";// 创建OSSClient实例。OSS ossClient = new OSSClientBuilder().build(endpoint, credentialsProvider);try {InputStream inputStream = new FileInputStream(filePath);// 创建PutObjectRequest对象。PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, objectName, inputStream);// 创建PutObject请求。PutObjectResult result = ossClient.putObject(putObjectRequest);} 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();}}
第三步:集成!!!!!!!!!

 引入工具类:这个工具类是用来把上传这个动作封装的,之后使用的画就直接把(文件,上传到云端保存的文件名)传入就可以实现上传功能,而其返回的数据就是文件在云端的访问地址

@Data
@AllArgsConstructor
@Slf4j
public class AliOssUtil {private String endpoint;private String accessKeyId;private String accessKeySecret;private String bucketName;/*** 文件上传** @param bytes* @param objectName* @return*/public String upload(byte[] bytes, String objectName) {// 创建OSSClient实例。OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);try {// 创建PutObject请求。ossClient.putObject(bucketName, objectName, new ByteArrayInputStream(bytes));} 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();}}//文件访问路径规则 https://BucketName.Endpoint/ObjectNameStringBuilder stringBuilder = new StringBuilder("https://");stringBuilder.append(bucketName).append(".").append(endpoint).append("/").append(objectName);log.info("文件上传到:{}", stringBuilder.toString());return stringBuilder.toString();}
}

配置云端密钥信息

  alioss:endpoint: oss-cn-beijing.aliyuncs.comaccess-key-id: LTAI5t7HRcgiCBRrRfPkzo6faccess-key-secret: XZOMsLJdTaZvKHKW5qS55nQrhh95Bfbucket-name: zzl-test-01

 封装一个实体类去加载我们的yml中的数据

@Component
@ConfigurationProperties(prefix = "sky.alioss")
@Data
public class AliOssProperties {private String endpoint;private String accessKeyId;private String accessKeySecret;private String bucketName;}

创建一个配置类,去创建工具类对象并交给bean容器管理

/*** 配置类*/
@Configuration
@Slf4j
public class OssConfiguration {@Bean@ConditionalOnMissingBeanpublic AliOssUtil aliOssUtil(AliOssProperties aliOssProperties){log.info("开始创建阿里云文件上传工具类对象:{}",aliOssProperties);return new AliOssUtil(aliOssProperties.getEndpoint(),aliOssProperties.getAccessKeyId(),aliOssProperties.getAccessKeySecret(),aliOssProperties.getBucketName());}
}

在接口中使用OSS工具类

@PostMapping("/upload")@ApiOperation("文件上传")public Result<String> upload(MultipartFile file){log.info("文件上传");try {//原始文件名String originalFilename = file.getOriginalFilename();//截取原始文件的类型,即获得文件的拓展名String extention = originalFilename.substring(originalFilename.lastIndexOf("."));String objectname = UUID.randomUUID().toString() + extention;//把文件的二进制形式和存储到云端的名字传给工具类,返回在云端的访问路径String filePath = aliOssUtil.upload(file.getBytes(), objectname);//把文件路径返回return Result.success(filePath);} catch (IOException e) {log.error("文件上传失败:{}",e);}return Result.error("文件上传失败");}

④mp多表联合分页查询,很硬但可以

 先展示一下自己实在直接硬搬代码的蠢办法,连多表查询都不需要:

public PageResult page(DishPageQueryDTO dishPageQueryDTO) {//创建Ipage对象IPage page = new Page(dishPageQueryDTO.getPage(),dishPageQueryDTO.getPageSize());//创建QueryWrapper对象进行条件筛选QueryWrapper wrapper = new QueryWrapper();wrapper.eq(dishPageQueryDTO.getCategoryId() != null,"category_id",dishPageQueryDTO.getCategoryId()).like(dishPageQueryDTO.getName() != null,"name",dishPageQueryDTO.getName()).eq(dishPageQueryDTO.getStatus() != null,"status",dishPageQueryDTO.getStatus());//进行查询dishMapper.selectPage(page, wrapper);List<Dish> records = page.getRecords();List<DishVO> dishVOS = new ArrayList<>();List<Category> name =new ArrayList<>();records.forEach(dish -> {DishVO dishVO = new DishVO();BeanUtils.copyProperties(dish,dishVO);dishVOS.add(dishVO);name.add(categoryService.query().eq("id",dish.getCategoryId()).select("name").one());});for(int i=0;i< dishVOS.size();i++){dishVOS.get(i).setCategoryName(name.get(i).getName());}//返回数据return new PageResult(page.getTotal(),dishVOS);}

不过再看了瑞吉外面的实现方法确实跟我这个差不了太多,都是直接把id提取出来去查过再放进链表中

        List<Dish> records = page.getRecords();List<DishVO> dishVOS = records.stream().map((item) -> {DishVO dishVO = new DishVO();BeanUtils.copyProperties(item, dishVO);Category byId = categoryService.getById(item.getCategoryId());dishVO.setCategoryName(byId.getName());return dishVO;}).collect(Collectors.toList());return  new PageResult(page.getTotal(),dishVOS);

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

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

相关文章

Redis学习4——Redis应用之限流

引言 Redis作为一个内存数据库其读写速度非常快&#xff0c;并且支持原子操作&#xff0c;这使得它非常适合处理频繁的请求&#xff0c;一般情况下&#xff0c;我们会使用Redis作为缓存数据库&#xff0c;但处理做缓存数据库之外&#xff0c;Redis的应用还十分广泛&#xff0c…

STM32接入CH340芯片的初始化进入升级模式(死机)问题处理

目录 1. 问题描述2. 问题分析2.1 CH340G/K 的初始化波形2.2 第1种USB升级电路2.3 第2种USB升级电路2.4 第3种USB升级电路2.5 第4种USB升级电路 3. 总结 1. 问题描述 我所用的CH340G&#xff08;CH340K也用过&#xff09;接在MCU的电路中&#xff0c;在插入CH340G/K 的接插件&a…

java10基础(this super关键字 重写 final关键字 多态 抽象类)

目录 一. this和super关键字 1. this关键字 2. super关键字 二. 重写 三. final关键字 四. 多态 五. 抽象类 1. 抽象方法 2. 抽象类 3. 面向抽象设计 一. this和super关键字 1. this关键字 this 当前对象的引用 this.属性 this.方法名() this() -- 调用构造函数 …

windows安装ElasticSearch以及踩坑

1.下载 elasticsearch地址&#xff1a;Past Releases of Elastic Stack Software | Elastichttps://www.elastic.co/cn/downloads/past-releases#elasticsearch IK分析器地址&#xff1a;infinilabs/analysis-ik: &#x1f68c; The IK Analysis plugin integrates Lucene IK…

【容器】k8s获取的节点oom事件并输出到node事件

在debug k8s node不可用过程中&#xff0c;有可能会看到: System OOM encountered, victim process: xx为了搞清楚oom事件是什么&#xff0c;以及如何产生的&#xff0c;我们做了一定探索&#xff0c;并输出了下面的信息。&#xff08;本文关注oom事件是如何生成&传输的&a…

每日一题(PTAL2):列车调度--贪心+二分

选择去维护一个最小区间 代码1&#xff1a; #include<bits/stdc.h> using namespace std; int main() {int n;cin>>n;int num;vector <int> v;int res0;for(int i0;i<n;i){cin>>num;int locv.size();int left0;int rightv.size()-1;while(left<…

2024/5/7 QTday2

练习&#xff1a;优化登录框&#xff0c;输入完用户名和密码后&#xff0c;点击登录&#xff0c;判断账户是否为 Admin 密码 为123456&#xff0c;如果判断成功&#xff0c;则输出登录成功&#xff0c;并关闭整个登录界面&#xff0c;如果登录失败&#xff0c;则提示登录失败&a…

【一看就懂】UART、IIC、SPI、CAN四种通讯协议对比介绍

UART、IIC、SPI、CAN四种通信协议对比 通信方式传输线通讯方式标准传输速度使用场景UARTTX(发送数据线)、RX(接收数据线)串行、异步、全双工115.2 kbit/s(常用)计算机和外部设备通信&#xff08;打印机&#xff09;IICSCL(时钟线)、SDA(数据线)串行、同步、半双工100 kbit/s(标…

文字转语音粤语怎么转换?6个软件教你快速进行文字转换语音

文字转语音粤语怎么转换&#xff1f;6个软件教你快速进行文字转换语音 当需要将文字转换为粤语语音时&#xff0c;可以使用多种工具和服务&#xff0c;这些工具可以帮助您快速而准确地实现这一目标。以下是六个非国内的语音转换软件&#xff0c;它们可以帮助您将文字转换为粤语…

FPGA学习笔记(3)——正点原子ZYNQ7000简介

1 ZYNQ-7000简介 ZYNQ 是由两个主要部分组成的&#xff1a;一个由双核 ARM Cortex-A9 为核心构成的处理系统&#xff08;PS&#xff0c;Processing System&#xff09;&#xff0c;和一个等价于一片 FPGA 的可编程逻辑&#xff08;PL&#xff0c;Programmable Logic&#xff0…

Linux 进程间通信之共享内存

&#x1f493;博主CSDN主页:麻辣韭菜&#x1f493;   ⏩专栏分类&#xff1a;Linux知识分享⏪   &#x1f69a;代码仓库:Linux代码练习&#x1f69a;   &#x1f339;关注我&#x1faf5;带你学习更多Linux知识   &#x1f51d; ​ 目录 ​编辑​ 前言 共享内存直接原理…

Mac虚拟机软件哪个好用 mac虚拟机parallels desktop有什么用 Mac装虚拟机的利与弊 mac装虚拟机对电脑有损害吗

随着多系统使用需求的升温&#xff0c;虚拟机的使用也变得越来越普遍。虚拟机可以用于创建各种不同的系统&#xff0c;并按照要求设定所需的系统环境。另外&#xff0c;虚拟机在Mac电脑的跨系统使用以及测试软件系统兼容性等领域应用也越来越广泛。 一、Mac系统和虚拟机的区别 …