苍穹外卖项目 常用注解 + 动态sql

news2024/12/28 9:24:51

常用注解

常见的注解解析方法有两种:

  • 编译期直接扫描:编译器在编译 Java 代码的时候扫描对应的注解并处理,比如某个方法使用@Override 注解,编译器在编译的时候就会检测当前的方法是否重写了父类对应的方法。
  • 运行期通过反射处理:像框架中自带的注解(比如 Spring 框架的 @Value、@Component)都是通过反射来进行处理的

这个博客对常用注解讲的很详细且有例子 SpringBoot常用的50个注解

以下是根据苍穹外卖来整理的注解和使用实例。
1.@ResponseBody
的作用其实是将java对象转为json格式的数据,然后直接写入HTTP response 的body中;
@RequestMapping后,返回值通常解析为跳转路径,但是加上 @ResponseBody 后返回结果不会被解析为跳转路径,而是直接写入 HTTP response body 中。
2.@RestController=@ReponseBody+@Controller
在类上用@RestController,其内的所有方法都会默认加上@ResponseBody,也就是默认返回JSON格式。将控制器方法的返回值转换为JSON格式,并以HTTP响应的方式返回给客户端。
@RestController和@Controller的共同点是都用来表示Spring某个类是否可以接收HTTP请求,二者区别: @RestController无法返回指定页面,而@Controller可以;前者可以直接返回数据,后者需要@ResponseBody辅助。

@RestController中指定Bean的名称。

@RestController("adminShopController")//为了避免两个Bean都叫shopController的冲突,所以用为了区分他俩
@RequestMapping("/admin/shop")
@Slf4j
@Api(tags = "店铺相关接口")
public class ShopController {
}
@RestController("UserShopController")
@RequestMapping("/user/shop")
@Api(tags = "店铺相关接口")
@Slf4j
public class ShopController {
}

3.@RequestBody作用在形参列表上,用于将前台发送过来固定格式的数据【xml格式 或者 json等】封装为对应的 JavaBean 对象,封装时使用到的一个对象是系统默认配置的 HttpMessageConverter进行解析,然后封装到形参上。
就是将JSON格式的数据封装到实体类中
4.@Transactional是Spring框架中用于声明式事务管理的关键注解。通过使用@Transactional注解,我们可以更加方便地管理事务,保障数据的一致性和可靠性。用于声明式事务管理**,保证方法或类中的操作在同一个事务中执行**。
5.@RequestMapping映射请求URL和处理方法。跳转路径
6.@GetMapping用于映射HTTP GET请求。
7.@PostMapping用于映射HTTP POST请求。
8. @RequestParam用于获取请求参数的值。

@DeleteMapping
@ApiOperation("菜品批量删除")
public Result delete(@RequestParam List<Long> ids){//注解@RequestParam,可以将地址栏中多个数字参数提取出来然后变成List集合。 
        log.info("菜品批量删除:{}",ids);
        dishService.deleteBatch(ids);
        return Result.success();
}

在这里插入图片描述
9. @ConfigurationProperties注解代表当前类是一个配置属性类,作用是:封装配置文件中的一些配置项。
原理就是:通过配置属性类,将配置文件中的配置项,封装成一个类,然后通过@Autowired注解注入到要使用的地方。
10.取的是路径参数,加注解@PathVariable,如果和路径参数不同名,就要加括号双引号指明取的是哪个路径参数@PathVariable("status") ;如果同名,就不用加。

	@PostMapping("/status/{status}")
    @ApiOperation("启用禁用员工账号")
    public Result startOrStop(@PathVariable Integer status,Long id){
        log.info("启用禁用员工账号:{},{}",status,id);
        employeeService.startOrStop(status,id);
        return Result.success();
}
  1. AOP相关注解
    切入点:对哪些类的哪些方法进行拦截。@Pointcut里面写的是对哪些方法进行拦截,要满足2点:①必须是mapper下的所有类的方法,②还要有AutoFill这个注解。
    在对切面的定义中共使用@Pointcut("execution(* com.sky.mapper.*.*(..)) && @annotation(com.sky.annotation.AutoFill)")这里指定使用的包范围

mapper中使用的示例:

 @AutoFill(OperationType.UPDATE)
    void update(Employee employee);

创建自定义注解
(1)annotation.AutoFill.java 注解类
@Target(ElementType.METHOD)//指定注解只能加载方法上,@Retention(RetentionPolicy.RUNTIME)运行时
Target注解指定加上什么上面,Retention注解指定什么时候用,

@Target(ElementType.METHOD)//指定注解只能加载方法上
@Documented
@Retention(RetentionPolicy.RUNTIME)
public @interface AutoFill {
    //通过枚举-指定当前属性OperationType
    //数据库操作类型OperationType:就两种 Update 和 Insert
    OperationType value();
}

(2)切面类 aspect.AutoFillAspect.java 自动填充的切片类

@Aspect
@Component
@Slf4j
public class AutoFillAspect {
    //这个包里的类和方法,同时还的是加上注解的
    @Pointcut("execution(* com.sky.mapper.*.*(..)) && @annotation(com.sky.annotation.AutoFill)")
    public void autoFillPointCut() {
    }
    //前置通知,在sql执行前加上即(公共字段赋值)
    @Before("autoFillPointCut()")//当匹配上切点表达式的执行这个
    public void autoFill(JoinPoint joinPoint) {//插入链接点的参数值
        //1.获取到当前被栏截的方法上的数据库操作类型
        //2.获取到当前被拦截的方法的参数--实体对象
        //3.准备赋值的数据
        //4.根据当前不同的操作类型,为对应的属性通过反射来赋值
    }
}

12.Swagger使用注解
在这里插入图片描述
@Api(tags = “员工相关接口”)

@RestController
@RequestMapping("/admin/employee")
@Slf4j
@Api(tags = "员工相关接口")//tags用来描述类的作用
public class EmployeeController {

@ApiOperation(“员工登录”)

	@PostMapping("/login")
    @ApiOperation("员工登录")
    public Result<EmployeeLoginVO> login(@RequestBody EmployeeLoginDTO employeeLoginDTO) {

@ApiModel(description = “员工登录时传递的数据模型”)
@ApiModelProperty(“用户名”)

@Data
@ApiModel(description = "员工登录时传递的数据模型")
public class EmployeeLoginDTO implements Serializable {

    @ApiModelProperty("用户名")
    private String username;

    @ApiModelProperty("密码")
    private String password;

}

13.@Bean //项目启动时就会调用方法创建对象
@ConditionalOnMissingBean//保证Spring容器里只有一个Util对象,条件对象当没Bean时再创建
注意要return的是这个新创建的对象,不然后面自动注入会失败,这里的主要目的就是创建Bean对象

@Bean //项目启动时就会调用方法创建对象
    @ConditionalOnMissingBean//保证Spring容器里只有一个Util对象,条件对象当没Bean时再创建
    public AliOssUtil aliOssUtil(AliOssProperties aliOssProperties) {
        return new AliOssUtil(aliOssProperties.getEndpoint(),
            aliOssProperties.getAccessKeyId(),
            aliOssProperties.getAccessKeySecret(),
            aliOssProperties.getBucketName());
    }

因为涉及到多个表,所以添加@Transactional的注解
(需要在启动类上添加@EnableTransactionManagement注解):开启注解方式的事务管理

@Transactional//涉及几多个数据表,需要保证数据一致性,需要事务注解--保证原子性,全成功或全失败
@Override
public void saveWithFlavor(DishDTO dishDTO) {
//开始新增菜品
}

15.Spring Cache框架,实现了基于注解的缓存功能。
在这里插入图片描述
都是在Controller层:
(1)@CachePut这个注释将方法的返回结果,user对象保存到Redis中,同时生成动态的key,userCache::user.id

@CachePut(cacheNames="userCache",key="abs")//Spring Cache缓存数据,key的生成:userCache:abc
@CachePut(cacheNames="userCache",key="#user.id")//与形参保持一致,或者
@CachePut(cacheNames="userCache",key="#result.id")//返回值result,或者
@CachePut(cacheNames="userCache",key="#p0.id")//获得当前方法的第一个参数user,或者
@CachePut(cacheNames="userCache",key="#a0.id")//获得当前方法的第一个参数user,或者
@CachePut(cacheNames="userCache",key="#root.args[0].id")//获得当前方法的第一个参数user
public User save(@RequestBody User user){
	userMapper.insert(user);
	return result;
}

插入完数据后,数据库生成的主键值会自动赋给user对象
Redis可以形成树形结构

(2)@Cacheable注解

@Cacheable(cahceNames="userCache"),key="#id")//key的生成,userCache::10
public User getById(Long id){
	User user = userMapper.getById(id);
	return user;
}

(3)@CacheEvict一次清理一条数据

@CacheEvict(cahceNames="userCache"),key="#id")//key的生成,userCache::10
public void deleteById(Long id){
	userMapper.deleteById(id);
}

清除所有数据

@CacheEvict(cahceNames="userCache"),allEntries=true)//userCache下的所有键值对
public void deleteAlld(){
	userMapper.deleteAll();
}

动态sql

insert 返回生成的主键值

<insert id="insert" useGeneratedKeys="true" keyProperty="id"><!-- 产生的主键值会赋给id属性-->
        insert into dish (name, category_id, price, image, description, create_time, update_time, create_user, update_user, status)
        values (#{name}, #{categoryId}, #{price}, #{image}, #{description}, #{createTime}, #{updateTime}, #{createUser}, #{updateUser}, #{status})
    </insert>

mapper:
不用注解,动态sql使用映射文件
在resource文件夹里都是xml文件

select

<select>标签的id是mapper中的对应方法名,resultType是返回的参数类型。

<select id="selectByPage" resultType="com.sky.entity.Employee">
        select * from employee
        <where>
            <if test="name!=null and name !='' ">
                and name like concat('%',#{name},'%') <!--模糊查询 like -->
            </if>
        </where>
        order by create_time desc <!--创建时间降序-->
</select>

稍复杂一点的select

动态sql
sql语句:左外链接:将左边的表的所有项与右边的表作连接
将菜和种类两个表按照种类id链接起来,以此获得种类名称

select d.*,c.name as categoryName from dish d left outer join category c on d.category_id=c.id

由于种类名称查出来也叫name,所以给字段起别名

<select id="pageQuery" resultType="com.sky.vo.DishVO">
        select d.*,c.name categoryName from dish d left join category c on d.category_id = c.id
        <where><!--毕竟动态sql。给它用where动态拼上DTO的3个属性 -->
            <if test="categoryId! =null">d.category_id=#{categoryId}</if>
            <if test="status!=null">d.status=#{status}</if>
            <if test="name!=null">d.name like concat('%',#{name},'%')</if>
        </where>
        order by d.create_time desc<!--根据创建时间降序 -->
    </select>

delete

(1)sql
按照菜id查全部信息,以此得到是否在售卖

@Select("select * from dish where id=#{id}")
    Dish getById(Long id);

(2)sql
是否有套餐关联
// select setmeal id from setmeal dish where dish_id in (1,2,3,4)
List queryUnsale(List ids);传入菜品List列表,用动态sql查每个菜品是否有套餐
SetMealDishMapper.xml

<select id="getSetmealIdsByDishIds" resultType="java.lang.Long">
        select setmeal_id from setmeal_dish where dish_id in
        <foreach collection="dishIds" separator="," item="id" open="(" close=")">
            #{id}
        </foreach>
    </select>

foreach循环,collection是集合,item是一个个项,separator是分割符号,open是开始符号,close是结束符号。每个元素用逗号分割,然后用大括号括起来。
(3)删除菜—传入为列表

<delete id="deleteBatch">
        delete from dish where id in
        <foreach collection="ids" item="id" separator="," open="(" close=")">
            #{id}
        </foreach>
    </delete>

(4)删除口味—传入为列表

<delete id="deleteBatchByDishIds">
        delete from dish_flavor where dish_id in
        <foreach collection="ids" item="id" open="(" close=")" separator=",">
            #{id}
        </foreach>
    </delete>

update

<update id="update">
        update dish
        <set>
            <if test="name!=null">name=#{name},</if>
            <if test="categoryId!=null">category_id=#{categoryId},</if>
            <if test="price!=null">price=#{price},</if>
            <if test="image!=null">image=#{image},</if>
            <if test="description!=null">description=#{description},</if>
            <if test="status!=null">status=#{status},</if>
            <if test="updateTime!=null">update_time=#{updateTime},</if>
            <if test="updateUser!=null">update_user=#{updateUser},</if>
        </set>
        where id=#{id}
    </update>

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

CesiumJS【Basic】- #038 绘制轮廓线(Primitive方式)

文章目录 绘制轮廓线(Primitive方式)1 目标2 代码2.1 main.ts绘制轮廓线(Primitive方式) 1 目标 使用Primitive方式绘制轮廓线 2 代码 2.1 main.ts var start = Cesium.Cartesian3.fromDegrees(-75.59777, 40.03883);v

设备通信-MODBUS协议和485接口

因水表远程监控和水泵数据监控系统&#xff0c;需了解物联网开发协议。 通信协议 通信协议说白了就是一种语言&#xff0c;一种通信双方都能听的懂得语言。 设备常用的通信协议有MODBUS RTU&#xff0c;PPI,MPI等&#xff0c;通信协议和我们常用的语言只是叫法不一样&#x…

预约小程序源码,云开发技术,无需服务器

介绍&#xff1a; 很多企业的业务都需要通过服务预约来完成&#xff0c;比如酒店、美容、家政等等。 但很多商家因缺少合适的服务预订工具&#xff0c;而不知道如何让客户尽快预约。 这种情况下&#xff0c;制作一个自己的预约小程序&#xff0c;客户只需要扫码或者在微信里…

8605 删数问题

这是一个典型的贪心算法问题。我们可以从高位开始&#xff0c;找到第一个比后面数字大的数字&#xff0c;删除它&#xff0c;然后继续这个过程&#xff0c;直到删除k个数字。如果我们已经删除了k个数字&#xff0c;但是还没有找到一个比后面数字大的数字&#xff0c;那么我们就…

51-1 内网信息收集 - 内网资源探测

导语 在内网渗透过程中,通常需要利用各种技术来探测内网资源,为后续的横向渗透做准备。发现内网存活的主机及其详细信息可以帮助确定攻击方向和潜在的漏洞。 一、基于 ICMP 发现存活主机 ICMP(Internet Control Message Protocol,因特网控制消息协议)是 TCP/IP 协议簇的…

Vue2动态代理,换服务无须重启项目

1、痛点 当我们需要使用不同的服务器时&#xff0c;就需要手动修改vue.config.js中配置并重新启动项目。当项目越来越大时&#xff0c;会需要较长的时间来等待项目启动&#xff0c;如此反复&#xff0c;极大影响我们开发进度。 2、寻求解决方案 vue-cli 的代理是使用的http-p…

详解归一化、标准化、正则化以及batch normalization

文章目录 what(是什么)where&#xff08;用在哪&#xff09;How&#xff08;如何用&&原理&#xff09;归一化实现方式原理示例说明 标准化实现方式原理示例说明 正则化实现方式原理作用 Batch Normalizationpytorch中的batch normalization原理BN的作用 归一化、标准化…

Python 文件操作

文件编码 将文件的内容翻译为二进制 文件操作 打开文件 open函数 语法&#xff1a; open(name, mode, encoding)name&#xff1a;文件名的字符串&#xff0c;可以包含具体路径。若没有路径&#xff0c;则默认为与py文件位于同一层 mode&#xff1a;打开文件的模式&#xf…

tkinter实现进度条

tkinter实现进度条 效果代码解析导入需要的模块定义进度条 代码 效果 代码解析 导入需要的模块 import tkinter as tk from tkinter import ttk定义进度条 def start_progress():progress[value] 0max_value 100step 10for i in range(0, max_value, step):progress[valu…

职场新宠“禁止蕉绿”:解压新方式,健康新态度

近期&#xff0c;一种名为“禁止蕉绿”的带杆香蕉在职场人群中悄然走红&#xff0c;成为他们工位上的新宠。这一现象源于“蕉绿”与“焦虑”的谐音&#xff0c;寓意着职场人对远离焦虑、追求心理放松的渴望。在社交平台上&#xff0c;种植水培果蔬如香蕉、菠萝等已成为职场话题…

一文带您了解Fiddler的家族产品:Fiddler Classic、FiddlerCore、Fiddler和Cap、Fiddler Jam

最近更新了一下Fiddler&#xff08;好久没更新了&#xff09;&#xff0c;然后浏览了一下官方网站&#xff0c;发现fillder的变化还是蛮大的&#xff0c;新出了好多产品&#xff0c;在这里我就把这些产品进行汇总比较&#xff0c;便于大家快速了解&#xff0c;快速选择自己需要…

为什么网络爬虫广泛使用HTTP代理?

一、引言 网络爬虫作为自动抓取互联网信息的重要工具&#xff0c;在现代社会中发挥着不可或缺的作用。然而随着网络环境的日益复杂&#xff0c;网站反爬虫技术的不断进步&#xff0c;网络爬虫在获取数据的过程中面临着越来越多的挑战。为了应对这些挑战&#xff0c;HTTP 代理成…

复制 pdf 的表格到 markdown 版本的Typora 或者 word 中

在 pdf 中选中复制表格内容&#xff0c;直接粘贴到 typora 中失败&#xff0c;可以使用 txt文件和 excel 做过渡。 准备一个空的 txt 文件&#xff0c;将 pdf 中表格的数据复制粘贴到txt文件中&#xff0c;文本内容会以空格分开&#xff0c;如下图的形式&#xff1a; 打开 exc…

【Excel、RStudio计算T检测的具体操作步骤】

目录 一、基础知识1.1 显著性检验1.2 等方差T检验、异方差T检验1.3 单尾p、双尾p1.3.1 检验目的不同1.3.2 用法不同1.3.3 如何选择 二、Excel2.1 统计分析工具2.1.1 添加统计分析工具2.1.2 数据分析 2.2 公式 -> 插入函数 -> T.TEST 三、RStudio 一、基础知识 参考: 1.…

Spring底层原理之bean的加载方式四 @import 注解

bean的加载方式四 import 第四种bean的导入方式 是import导入的方式 在配置类上面加上注解就行 package com.bigdata1421.config;import com.bigdata1421.bean.Dog; import org.springframework.context.annotation.Import;Import(Dog.class) public class SpringConfig4 {…

直播的js代码debug解析找到protobuf消息的定义

我们都知道直播的弹幕消息是通过websocket发送的&#xff0c;而且是通过protobuf传输的&#xff0c;那么这里面传输了哪些内容&#xff0c;这个proto文件又要怎么定义&#xff1f;每个消息叫什么&#xff0c;消息里面又包含有哪些字段&#xff0c;每个字段又是什么类型&#xf…

1-3.文本数据建模流程范例

文章最前&#xff1a; 我是Octopus&#xff0c;这个名字来源于我的中文名–章鱼&#xff1b;我热爱编程、热爱算法、热爱开源。所有源码在我的个人github &#xff1b;这博客是记录我学习的点点滴滴&#xff0c;如果您对 Python、Java、AI、算法有兴趣&#xff0c;可以关注我的…

# [0701] Task05 策略梯度、Actor-critic 算法

easy-rl PDF版本 笔记整理 P4、P9 joyrl 比对 补充 P9 - P10 相关 代码 整理 最新版PDF下载 地址&#xff1a;https://github.com/datawhalechina/easy-rl/releases 国内地址(推荐国内读者使用)&#xff1a; 链接: https://pan.baidu.com/s/1isqQnpVRWbb3yh83Vs0kbw 提取码: us…

LeetCode中MySQL题目 176.第二高的薪水

题目图片&#xff1a; 题目解答&#xff1a; SELECTIFNULL((SELECT DISTINCT SalaryFROM EmployeeORDER BY Salary DESCLIMIT 1 OFFSET 1),NULL) AS SecondHighestSalary解答解析&#xff1a; 就是用了一个叫做IFNULL的函数进行判断&#xff0c;如果查找出来的内容为空&…

信息系统的安全模型

1. 信息系统的安全目标 信息系统的安全目标是控制和管理主体&#xff08;含用户和进程&#xff09;对客体&#xff08;含数据和程序&#xff09;的访问。作为信息系统安全目标&#xff0c;就是要实现&#xff1a; 保护信息系统的可用性&#xff1b; 保护网络系统服务的…