【苍穹外卖 | 项目日记】第二天

前言:

        坦率的讲今天有点水,课也多,上了一天课,中午下课后和晚上十一点多跑完步回来写了两个接口

【苍穹外卖 | 项目日记】第二天_第1张图片

目录

前言:

今日完结任务:

 今日收获:

1.实现了公共字段填充功能

2.实现了文件上传接口

杂项知识点:

总结:


 

 

今日完结任务:

  • 实现了公共字段填充功能
  • 实现了文件上传接口

 今日收获:

1.实现了公共字段填充功能

我们的项目开发中会牵扯大量的数据表,而这些数据表中有一些重叠的字段,我们把他们叫做公共字段,例如菜品种类表和员工表里面都有修改人/时间 以及 创建人/时间 四个公共的字段,而且代码也基本一致,都是给对象赋值然后传递到mapper层进行数据库操作,而大量相似的代码会造成代码的冗余,因此我们对此方面进行优化:
优化前:
【苍穹外卖 | 项目日记】第二天_第2张图片

我们优化的思想是AOP思想

【Spring知识点介绍 | 第二篇】什么是AOP_我是一盘牛肉的博客-CSDN博客

简单的来讲,就是把所有需要对这四个字段进行修改的方法提前进行拦截,在我们的 通知 中就对这四个字段进行赋值,然后再进行被拦截的方法。(由此可以看出我们这里的通知是前置通知

拦截我们这里采用的方法是自定义注解,自定义一个方法注解,被该注解标记的方法会被拦截器拦截。

【苍穹外卖 | 项目日记】第二天_第3张图片

这里简单贴一部分代码:
【苍穹外卖 | 项目日记】第二天_第4张图片

使用AOP思想的好处就是我们在不改动源代码的前提下 实现了对目标代码的优化,这对于大型项目有很大的优点。

此外在这个方法中我还学到了两个注解:
1.@target注解

@Target 是 Java 注解中的一个元注解,用于指定注解可以应用的目标元素类型。它可以用来约束一个注解可以在哪些地方使用。@Target 注解包含一个 value 属性,其值是一个枚举数组,表示注解可以应用的目标元素类型。常见的目标元素类型包括:

  • ElementType.TYPE:可以应用在类、接口、枚举等类型上。
  • ElementType.FIELD:可以应用在字段上。
  • ElementType.METHOD:可以应用在方法上。
  • ElementType.PARAMETER:可以应用在方法参数上。
  • ElementType.CONSTRUCTOR:可以应用在构造函数上。
  • ElementType.LOCAL_VARIABLE:可以应用在局部变量上。
  • ElementType.ANNOTATION_TYPE:可以应用在注解上。
  • ElementType.PACKAGE:可以应用在包上。

2.@Retention注解

@Retention 是 Java 注解中的一个元注解,用于指定注解的保留策略,即注解在何时生效。它可以用来约束一个注解可以保留多长时间。@Retention 注解包含一个 value 属性,其值是一个枚举类型 RetentionPolicy 的枚举常量。

常见的保留策略包括:

  • RetentionPolicy.SOURCE:注解仅保留在源代码中,编译时会被忽略。这意味着在编译后的字节码中不会包含该注解。
  • RetentionPolicy.CLASS:注解保留在编译后的字节码中,但在运行时不可见。这是默认的保留策略,如果在注解上没有明确指定保留策略,默认为 CLASS。
  • RetentionPolicy.RUNTIME:注解保留在编译后的字节码中,并在运行时可见。这意味着可以通过反射机制在运行时获取并解析注解信息。

2.实现了文件上传接口

这里的文件上传主要是图片文件,我们整体的思路是 利用阿里云OSS服务器,把图片上传到阿里云的OSS服务器后,利用后端接收OSS服务器返回的图片URL,然后再返回给前端,前端调用URL进行图片回显。

其实这个接口整体的思路很简单,没有什么创新的点,在这里我也简单的贴出来一部分代码:

【苍穹外卖 | 项目日记】第二天_第5张图片
【苍穹外卖 | 项目日记】第二天_第6张图片

 在写这个接口的时候,我们把AliyunOSSutils  对象交给了IOC容器管理,并在实现方法中自动装配,实现了解耦

这里我介绍一下这个代码中给我启发性的两点:
1.使用UUID生成文件名

这里我们使用的OSS云服务需要给上传后的文件命名,而重复的命名会导致文件被覆盖,因此我们使用UUID工具类来生成一串随机数,把这个随机数作为文件名,这样文件就不会被覆盖。

2.不要把配置类写死

我们在配置类文件中配置aliyunOSS位置信息的时候,不要直接写死,应该写成这种格式(即让A配置类引用B配置类)

【苍穹外卖 | 项目日记】第二天_第7张图片

也就是说引用另一个配置类中的信息,这是因为我们的项目会经历开发,测试,维护三个阶段,而这三个阶段可能使用的数据库等等配置类不一致,因此我们不要在配置类中把配置类写死

而是再写一个配置类,例如dev(开发配置类),让目标配置类引用开发配置类:

【苍穹外卖 | 项目日记】第二天_第8张图片

引用dev中的配置类 

18d4f435b03a4627ae9b5d6b8d0240a5.png

这样当我们切换环境的时候,直接修改active中的配置类就好了,而不用在配置类中一个一个修改。

杂项知识点:

什么叫做逻辑外键:

逻辑外键是在关系数据库中的一个概念,它是通过程序或规则实现的关联关系,而不是通过数据库引擎的外键约束来实现的。在逻辑外键中,没有在数据库模式中显式定义外键约束,但是应用程序或业务规则会处理相关的关联逻辑。

简单的说:逻辑外键就是在数据库中并没有使用外键的形式把两张表关联起来,而是在业务层用代码实现对表进行逻辑关系绑定。

通过反射来拿到一个类的方法

这个知识点的应用场景是公共字段填充功能,我们先贴代码再进行解释

【苍穹外卖 | 项目日记】第二天_第9张图片

我们利用连接点拿到了第一个参数(这里我们默认第一个参数就是需要进行字段填充的对象),而此时arg的类型并不明确,他可能是emplyee,也可能是category。因此我们无法直接用arg来调用对应的参数方法。

而这里我们的解决思路是利用反射

Method setCreateTime = arg.getClass().getDeclaredMethod(AutoFillConstant.SET_CREATE_TIME, LocalDateTime.class);
Method setCreaterUser = arg.getClass().getDeclaredMethod(AutoFillConstant.SET_CREATE_USER, Long.class);
Method setUpdateTime = arg.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class);
Method setUpdateUser = arg.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_USER, long.class);

我们取第一条解释一下:

首先,arg.getClass() 返回 arg 对象的运行时类,即获取到 arg 对象的类对象。接着,getDeclaredMethod(AutoFillConstant.SET_CREATE_TIME, LocalDateTime.class) 是调用类对象的 getDeclaredMethod 方法,并传入两个参数。第一个参数是要获取的方法的名称,AutoFillConstant.SET_CREATE_TIME 表示要获取的方法名。第二个参数是方法的参数类型,LocalDateTime.class 表示要获取的方法的参数类型为 LocalDateTime。
getDeclaredMethod 方法会返回一个 Method 对象,表示指定名称和参数类型的方法。如果找不到对应的方法,会抛出 NoSuchMethodException 异常。
然后,将获取到的方法对象赋值给 setCreateTime 变量。

而我们通过反射就拿到了类中的方法

之后再利用invoke方法进行赋值,就完成了对象字段的填充

【苍穹外卖 | 项目日记】第二天_第10张图片

由此我们可以看出反射也是一个很高级的知识点,它使得我们能对未知类型的对象进行调用其类中的特有方法。 

总结:

        今天虽然实现的接口少,但是我的收获也很大,明天的课很少,打算一直在宿舍些项目了。写项目真的是一个很畅快的过程。

如果我的内容对你有帮助,请点赞,评论,收藏。创作不易,大家的支持就是我坚持下去的动力!

69e9169c980f43e0aad31ff9ada88a9c.png

 

 

你可能感兴趣的:(【苍穹外卖】,spring,数据库,java,后端,spring,boot)