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

常用注解

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

  • 编译期直接扫描:编译器在编译 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 和 InsertOperationType value();
}

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

@Aspect
@Component
@Slf4j
public class AutoFillAspect {//这个包里的类和方法和加上@AutoFill注解的@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.mzph.cn/diannao/39277.shtml

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

相关文章

【基于R语言群体遗传学】-3-计算等位基因频率

书接上文&#xff0c;我们讲完了哈代温伯格基因型频率&#xff0c;也使用数据进行了拟合&#xff0c;那么接下来就是考虑一些计算的问题&#xff1a; 【基于R语言群体遗传学】-1-哈代温伯格基因型比例-CSDN博客 【基于R语言群体遗传学】-2-模拟基因型&#xff08;simulating …

WebKey备受瞩目的Web3.0新叙事,硬件与加密生态完美融合特性成为数字世界的新入口

在当今迅速发展的科技领域&#xff0c;Web3.0正在引领一场颠覆性的变革。而作为这一变革的先锋&#xff0c;WebKey无疑是备受瞩目的创新项目。它不仅代表了一种全新的技术趋势&#xff0c;更是数字世界中硬件与加密生态完美融合的典范。 硬件与加密生态的完美融合 WebKey的核心…

【QT】输入类控件

目录 Line Edit 核心属性 核心信号 正则表达式 示例&#xff1a;使用正则表达式验证输入框内容 示例&#xff1a;切换输入框密码模式下的显示状态 Text Edit 核心属性 核心信号 示例&#xff1a;获取多行输入框的内容同步显示到label 示例&#xff1a;获取文本的选…

一文讲懂npm link

前言 在本地开发npm模块的时候&#xff0c;我们可以使用npm link命令&#xff0c;将npm 模块链接到对应的运行项目中去&#xff0c;方便地对模块进行调试和测试 用法 包链接是一个两步过程&#xff1a; 1.为依赖项创建全局软链npm link。一个符号链接&#xff0c;简称软链&a…

二刷力扣——DP算法(子序列问题)

300. 最长递增子序列 定义是以本元素结尾&#xff0c;所以公式初始化都好弄。但是太慢 class Solution {public int lengthOfLIS(int[] nums) {int nnums.length;int[] dp new int[n];//以自己结尾的最长递增子序列dp[0]1;int maxzi1;for(int i1;i<n;i){dp[i]1;for(int j…

QT中QDomDocument读写XML文件

一、XML文件 <?xml version"1.0" encoding"UTF-8"?> <Begin><Type name"zhangsan"><sex>boy</sex><school>Chengdu</school><age>18</age><special>handsome</special>&l…

【YOLOv5进阶】——引入注意力机制-以SE为例

声明&#xff1a;笔记是做项目时根据B站博主视频学习时自己编写&#xff0c;请勿随意转载&#xff01; 一、站在巨人的肩膀上 SE模块即Squeeze-and-Excitation 模块&#xff0c;这是一种常用于卷积神经网络中的注意力机制&#xff01;&#xff01; 借鉴代码的代码链接如下&a…

在C#中使用RabbitMQ做个简单的发送邮件小项目 _

前言 好久没有做项目了&#xff0c;这次做一个发送邮件的小项目。发邮件是一个比较耗时的操作&#xff0c;之前在我的个人博客里面回复评论和友链申请是会通过发送邮件来通知对方的&#xff0c;不过当时只是简单的进行了异步操作。那么这次来使用RabbitMQ去统一发送邮件&#x…

vue中路由来回切换页面直接卡死

今天发现一个很严重的问题&#xff0c;项目好不容易做好了&#xff0c;结果页面多了&#xff0c;切换之后卡死。页面所有的交互效果都失效了。 排查了许久的错误原因最后发现原来是路由名称重复了。 如上图当页面跳转到riskdetails详细页面之后&#xff0c;框架则被这个详情页…

node.lib下载失败,手动下载并配置

在无网络环境&#xff0c;或者网络不好的环境&#xff0c;node.lib会下载失败&#xff0c;此时可手动下载并进行配置。 我们以 node16.17.0 为例&#xff1a; 下载地址 分别下载node.lib和headers https://registry.npmmirror.com/-/binary/node/v16.17.0/win-x64/node.lib…

Linux rpm与yum

一、rpm包管理 rpm用于互联网下载包的打包及安装工具&#xff0c;它包含在某些Linux分发版中。它生成具有.RPM扩展名的文件。RPM是RedHat Package Manager (RedHat软件包管理工具&#xff09;的缩写&#xff0c;类似windows的setup.exe&#xff0c;这一文件格式名称虽然打上了R…

办理北京公司注销流程和步骤说明

公司的生命周期是多变的&#xff0c;有时候&#xff0c;业务可能会结束或者出现其他原因&#xff0c;需要注销公司。注销公司是一个复杂的法律过程&#xff0c;需要遵循一系列的步骤和提交特定的材料。下面我们将详细介绍北京注销公司的流程以及需要准备的材料&#xff0c;以帮…

私有云统一多云管理平台主要服务内容

私有云统一多云管理平台&#xff0c;作为企业IT架构现代化的关键组成部分&#xff0c;旨在为企业提供高效、灵活、安全的云计算资源管理解决方案。这类平台通过整合和优化不同云环境(包括私有云、公有云、混合云)的管理&#xff0c;帮助企业打破云孤岛&#xff0c;实现资源的统…

【游戏引擎之路】登神长阶(五)

5月20日-6月4日&#xff1a;攻克2D物理引擎。 6月4日-6月13日&#xff1a;攻克《3D数学基础》。 6月13日-6月20日&#xff1a;攻克《3D图形教程》。 6月21日-6月22日&#xff1a;攻克《Raycasting游戏教程》。 6月23日-6月30日&#xff1a;攻克《Windows游戏编程大师技巧》。 …

【Qwen2部署实战】Qwen2初体验:用Transformers打造智能聊天机器人

系列篇章&#x1f4a5; No.文章1【Qwen部署实战】探索Qwen-7B-Chat&#xff1a;阿里云大型语言模型的对话实践2【Qwen2部署实战】Qwen2初体验&#xff1a;用Transformers打造智能聊天机器人3【Qwen2部署实战】探索Qwen2-7B&#xff1a;通过FastApi框架实现API的部署与调用4【Q…

从任意用户注册到任意密码重置

写在最前面一句话 To be or not to be ,it‘s a question . 哎呀&#xff0c;放错台词了&#xff0c;应该是 true or false , 在最近的测试中遇到了一个很有趣的点 “将 false 改为true ”就可以成功绕过验证码了。 T rue or false &#xff1f;&#xff1f;&#xff1f; …

「51媒体」企业举行新闻发布会,如何邀请媒体到场报道

传媒如春雨&#xff0c;润物细无声&#xff0c;大家好&#xff0c;我是51媒体网胡老师。 媒体宣传加速季&#xff0c;100万补贴享不停&#xff0c;一手媒体资源&#xff0c;全国100城线下落地执行。详情请联系胡老师。 企业举行新闻发布会时&#xff0c;邀请媒体到场报道是一个…

MySQL常用操作命令大全

文章目录 一、连接与断开数据库1.1 连接数据库1.2 选择数据库1.3 断开数据库 二、数据库操作2.1 创建数据库2.2 查看数据库列表2.3 删除数据库 三、表操作3.1 创建表3.2 查看表结构3.3 修改表结构3.3.1 添加列3.3.2 删除列3.3.3 修改列数据类型 3.4 删除表 四、数据操作4.1 插入…

day62--若依框架(基础应用篇)

若依搭建 若依版本 官方 若依官方针对不同开发需求提供了多个版本的框架&#xff0c;每个版本都有其独特的特点和适用场景&#xff1a; 前后端混合版本&#xff1a;RuoYi结合了SpringBoot和Bootstrap的前端开发框架&#xff0c;适合快速构建传统的Web应用程序&#xff0c;其…

Qt加载SVG矢量图片,放大缩小图片质量不发生变化。

前言&#xff1a; 首先简单描述下SVG: SVG 意为可缩放矢量图形&#xff08;Scalable Vector Graphics&#xff09;。 SVG 使用 XML 格式定义图像。 给界面或者按钮上显示一个图标或背景图片&#xff0c;日常使用.png格式的文件完全够用&#xff0c;但是有些使用场景需要把图…