下面我会对自己在项目开发过程中遇到的常用的spring 注解进行总结方便以后学习(不定期更新)
@CommponentScan
@ComponentScan 注解类,使得 Spring 去扫描指定包路径下面的类,找到标注有@Component,@Controller,@Service,@Repository 注解的类,将这些类自动加载到 Spring 容器中
其中,@Controller,@Service,@Repository 注解都标注了@Component 注解,因此本质上,都是根据@Component 注解来判断对象否要加载到容器中。
通常@ComponentScan 注解都是和@Configuration 注解一起使用,一起用来作为 Spring 配置的一部分。
筛选功能
@ComponentScan 中在扫描类的时候,通过对属性 includeFilters 和 excludeFilters 的设置,可以有对于类型有一个筛选功能。includeFilters 指定了哪些类才能被扫描到,excludeFilters 则相反,指定了哪些类得排除扫描。
下面代码中标注有@Service 注解的类,会被排除,不会被加载到 Spring 容器中。includeFilters 也有同样的功能,不再举例。
1 |
|
@Mapper
通用Mapper就是为了解决单表增删改查,基于Mybatis的插件。
使用Mybatis的开发者,大多数都会遇到一个问题,就是要写大量的SQL在xml文件中,除了特殊的业务逻辑SQL之外,还有大量结构类似的增删改查SQL。而且,当数据库表结构改动时,对应的所有SQL以及实体类都需要更改。这工作量和效率的影响或许就是区别增删改查程序员和真正程序员的屏障。这时,通用Mapper便应运而生
通用Mapper就是为了解决单表增删改查,基于Mybatis的插件。开发人员不需要编写SQL,不需要在DAO中增加方法,只要写好实体类,就能支持相应的增删改查方法。 一旦继承了Mapper,继承的Mapper就拥有了Mapper所有的通用方法:
Select
方法:List
select(T record);
说明:根据实体中的属性值进行查询,查询条件使用等号
方法:T selectByPrimaryKey(Object key);
说明:根据主键字段进行查询,方法参数必须包含完整的主键属性,查询条件使用等号
方法:List
selectAll();
说明:查询全部结果,select(null)方法能达到同样的效果
方法:T selectOne(T record);
说明:根据实体中的属性进行查询,只能有一个返回值,有多个结果是抛出异常,查询条件使用等号
方法:int selectCount(T record);
说明:根据实体中的属性查询总数,查询条件使用等号
Insert
方法:int insert(T record);
说明:保存一个实体,null的属性也会保存,不会使用数据库默认值
方法:int insertSelective(T record);
说明:保存一个实体,null的属性不会保存,会使用数据库默认值
Update
方法:int updateByPrimaryKey(T record);
说明:根据主键更新实体全部字段,null值会被更新
方法:int updateByPrimaryKeySelective(T record);
说明:根据主键更新属性不为null的值
Delete
方法:int delete(T record);
说明:根据实体属性作为条件进行删除,查询条件使用等号
方法:int deleteByPrimaryKey(Object key);
说明:根据主键字段进行删除,方法参数必须包含完整的主键属性
Example方法
方法:List
selectByExample(Object example);
说明:根据Example条件进行查询
重点:这个查询支持通过Example类指定查询列,通过selectProperties方法指定查询列
方法:int selectCountByExample(Object example);
说明:根据Example条件进行查询总数
方法:int updateByExample(@Param(“record”) T record, @Param(“example”) Object example);
说明:根据Example条件更新实体record包含的全部属性,null值会被更新
方法:int updateByExampleSelective(@Param(“record”) T record, @Param(“example”) Object example);
说明:根据Example条件更新实体record包含的不是null的属性值
方法:int deleteByExample(Object example);
说明:根据Example条件删除数据
@Table
spring @Table注解 作用是 : 声明此对象映射到数据库的数据表,通过它可以为实体指定表(talbe)
常用的两个属性
name 用来命名 当前实体类 对应的数据库 表的名字
@Table(name = “user_role”)
等价于Mybatis-plus中的 @TableName(“user_role”)
uniqueConstraints 用来批量命名唯一键
@Table(name = “user_role”,uniqueConstraints = {@UniqueConstraint(columnNames={“uid”,”email”})})
@TableId
设置主键映射 value映射主键字段的名字
type 设置主键类型 主键的生成策略 (圈起来的重要)
AUTO
开发者无需赋值,自己根据当前表中id最大值自增+1NONE
自动生成主键 使用雪花算法,数据类型改int为longINPUT
如果插入操作中,没有对id进行赋值,那么存进数据库中的将为0(long),数据库一般会采取自增id的方式处理 当前数据库编号的值+1,如果给定值了,就用给定的值ASSIGN_ID
使用mp自动赋值 采取雪花算法ASSIGN_UUID
要求主键类型必须是String类型,会自动生成UUID进行赋值
@TableField
非主键字段使用,比如数据中的表中的字段是name,但是实体类是userName,那么就需要在userName上打上这个注解
exit 表示是否为是数据库字段
在VO DTO的时候,经常会查询一些数据库中没有的字段,如果没有打上标签,那么查询会报错(如果实体类中的成员变脸在数据库中没有对应字段,可以视同),需要设置为false,表示为非数据库字段,那么查询的时候就不会报错select 表示是否查询该字段
加上不参与查询,并且返回nullfill 表示是否自动填充
将对象存入数据的时候,由mybatisplus自动给某些字段赋值,create_time update_time 比如说注册的时间和修改时间是基本上每个表都会用到的,实现起来就是获取时间存入DEFAUL*T –默认不处理
INSERT* –插入时填充字段(第一次添加的时候)
INSERT_UPDATE* –插入和更新时填充字段(最近一次更新的时候,也就是插入和更新都满足)
UPDATE* –更新时填充字段
@Veresion
标记乐观锁
1、主修改操作
2、防止数据被重复操作
3、防止两个线程同时操作同一个数据,保证数据的安全性
原理
标记乐观锁,通过version字段来保证数据的安全性,当修改数据的时候,会以version作为条件,当条件成立的时候才会修改成功。
@Accessors
Accessor的中文含义是存取器,是基于lombok的插件,@Accessors用于配置getter和setter方法的生成结果
下面介绍三个属性:
fluent
fluent的中文含义是流畅的,设置为true,则getter和setter方法的方法名都是基础属性名,且setter方法返回当前对象chain
chain的中文含义是链式的,设置为true,则setter方法返回当前对象prefix
prefix的中文含义是前缀,用于生成getter和setter方法的字段名会忽视指定前缀(遵守驼峰命名)
1 | //fluent |
@Service
此注注解属于业务逻辑层,service或者manager层
@Service(“serviceName”)注解相当于applicationContext.xml配置文件中配置的
1 | "courseDAO") ( |
其作用相当于在applicationContext.xml配置文件里配置如下信息
1 | <bean id="courseDAO" |
@Antowired
这个注解就是spring可以自动帮你把bean里面引用的对象的setter/getter方法省略,它会自动帮你set/get。
@Autowired 是一个注释,它可以对类成员变量、方法及构造函数进行标注,让 spring 完成 bean 自动装配的工作。
@Autowired 默认是按照类去匹配,配合 @Qualifier 指定按照名称去装配 bean。
1 | import org.springframework.beans.factory.annotation.Autowired; |
@Transactional
@Transactional 是声明式事务管理 编程中使用的注解
事务管理是应用系统开发中必不可少的一部分。Spring 为事务管理提供了丰富的功能支持。Spring 事务管理分为编码式和声明式的两种方式。编程式事务指的是通过编码方式实现事务;声明式事务基于 AOP,将具体业务逻辑与事务处理解耦。声明式事务管理使业务代码逻辑不受污染, 因此在实际使用中声明式事务用的比较多。声明式事务有两种方式,一种是在配置文件(xml)中做相关的事务规则声明,另一种是基于@Transactional 注解的方式。注释配置是目前流行的使用方式
需要注意
- 默认配置下 Spring 只会回滚运行时、未检查异常(继承自 RuntimeException 的异常)或者 Error
- @Transactional 注解只能应用到 public 方法才有效
简单的使用方法
只需在方法加上 @Transactional 注解就可以了。
如下有一个保存用户的方法,加入 @Transactional 注解,使用默认配置,抛出异常之后,事务会自动回滚,数据不会插入到数据库。
1 |
|
@RequiresRoles
验证当前用户是否具有某角色,与验证权限类似
当前Subject必须拥有所有指定的角色时,才能访问被该注解标注的方法。如果当天Subject不同时拥有所有指定角色,则方法不会执行还会抛出AuthorizationException异常。
使用这注解的前提是会进入到Realm的doGetAuthorizationInfo()授权方法中。
1 | //授权 |
设置访问权限
1 | //示例 |
感谢csnd博主一只沙雕的分享,有兴趣请参考 文章
@RequiresPermissions
当前Subject需要拥有某些特定的权限时,才能执行被该注解标注的方法。如果当前Subject不具有这样的权限,则方法不会被执行。
1 | //源码 |
上面加了RequiresPermissions。那么只有当用户拥有这个getUserByCondition字符串时才能访问方法getUserByCondition()。
那么该注解具体如何运转的呢?
首先在这我自己定义了一个方法MyRealm,继承抽象方法 org.apache.shiro.realm.AuthorizingRealm 实现其抽象类doGetAuthorizationInfo方法,这样框架就会取到用户权限列表,然后判断用户当前角色是否符合该角色权限
1 | //示例 |
@FeignClient
由于SpringCloud采用分布式微服务架构,难免在各个子模块下存在模块方法互相调用的情况。比如service-admin服务要调用service-card 服务的方法。
@FeignClient()注解就是为了解决这个问题的。
@FeignClient()注解的源码要求它必须在Interface接口上使用。( FeignClient注解被@Target(ElementType.TYPE)修饰,表示FeignClient注解的作用目标在接口上)
关于调用目前有两种:
接口提供方在注册中心
如果服务提供方已经注册到注册中心了,那么name或者value的值为:服务提供方的服务名称。必须为所有客户端指定一个name或者value
@FeignClient(value=”run-product”,fallback = ProductClientServiceFallBack.class)单独的一个http接口,接口提供方没有到注册中心
@FeignClient(name=”runClient11111”,url=”localhost:8001”)
此处name的值为:调用客户端的名称。
1 | "feign-server",configuration = FeignConfig.class) //需要一个配置文件 (value = |
@FeignClient标签的常用属性如下:
- value: 服务名
- name:指定FeignClient的名称,如果项目使用了Ribbon,name属性会作为微服务的名称,用于服务发现
- url: url一般用于调试,可以手动指定@FeignClient调用的地址
- decode404:当发生http 404错误时,如果该字段位true,会调用decoder进行解码,否则抛出FeignException
- configuration: Feign配置类,可以自定义Feign的Encoder、Decoder、LogLevel、Contract
- fallback: 定义容错的处理类,当调用远程接口失败或超时时,会调用对应接口的容错逻辑,fallback指定的类必须实现@FeignClient标记的接口
- fallbackFactory: 工厂类,用于生成fallback类示例,通过这个属性我们可以实现每个接口通用的容错逻辑,减少重复的代码
- path: 定义当前FeignClient的统一前缀
此外还要求服务的启动类要有@EnableFeignClients 注解才能使Fegin生效