Swagger
来源:https://juejin.cn/post/6951736202613489672
@Api:用在请求的类上,表示对类的说明
tags="说明该类的作用,可以在UI界面上看到的注解"
value="该参数没什么意义,在UI界面上也看到,所以不需要配置"
@ApiOperation:用在请求的方法上,说明方法的用途、作用
value="说明方法的用途、作用"
notes="方法的备注说明"
@ApiImplicitParams:用在请求的方法上,表示一组参数说明
@ApiImplicitParam:用在@ApiImplicitParams注解中,指定一个请求参数的各个方面
name:参数名
value:参数的汉字说明、解释
required:参数是否必须传
paramType:参数放在哪个地方
· header --> 请求参数的获取:@RequestHeader
· query --> 请求参数的获取:@RequestParam
· path(用于restful接口)--> 请求参数的获取:@PathVariable
· div(不常用)
· form(不常用)
dataType:参数类型,默认String,其它值dataType="Integer"
defaultValue:参数的默认值
@ApiResponses:用在请求的方法上,表示一组响应
@ApiResponse:用在@ApiResponses中,一般用于表达一个错误的响应信息
code:数字,例如400
message:信息,例如"请求参数没填好"
response:抛出异常的类
@ApiModel:用于响应类上,表示一个返回响应数据的信息
(这种一般用在post创建的时候,使用@RequestBody这样的场景,
请求参数无法使用@ApiImplicitParam注解进行描述的时候)
@ApiModelProperty:用在属性上,描述响应类的属性
swagger-ui 版本 2.7.0就是下图样式(最直观,个人觉得最好用)
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.7.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.7.0</version>
</dependency>
使用@RequestBody就是接收json格式的数据
@ApiOperation("修改支付接口")
@PutMapping("/auth/update")
public Result update(@RequestBody PaymentInterface paymentInterface) {
}
接收非json格式的数据
注解
@Validated && @Valid
https://blog.csdn.net/qq_32352777/article/details/108424932
MybatisPlus
多看官方文档
开源仓库:https://gitee.com/baomidou/mybatis-plus-samples/tree/master
代码 在 test目录下 sql文件在resource目录下
mybatis-plus-sample-generator: 代码生成器示例
mybatis-plus-sample-crud: 完整 CRUD 示例
mybatis-plus-sample-wrapper: 条件构造器示例
mybatis-plus-sample-pagination: 分页功能示例
…
来源:https://blog.csdn.net/qq_34508530/article/details/88945034
简化CURD
相比两种写法,我更喜欢ActiveRecord的模式写法,因为我不用注入userMapper,new了一个对象之后直接调用方法操作就行了,复杂的查询也很简单,新建一个EntityWrapper作为查询对象,Wrapper接口封装了很多常用的方法。几乎sql能写出来的条件调用Wrapper的方法就能表现出来。
插入返回主键id值
new User();
insert(user)
int id=user.getId()
service继承了ServiceImpl,自己看源码,许多简单的业务可以直接在controller层调用service接口实现类操作,例如:remove,get,update,list等函数(没有 insert)
BaseMapper的源码:
public interface BaseMapper<T> extends Mapper<T> {
int insert(T entity);
int deleteById(Serializable id);
int deleteByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);
int delete(@Param(Constants.WRAPPER) Wrapper<T> wrapper);
int deleteBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);
int updateById(@Param(Constants.ENTITY) T entity);
int update(@Param(Constants.ENTITY) T entity, @Param(Constants.WRAPPER) Wrapper<T> updateWrapper);
T selectById(Serializable id);
List<T> selectBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);
List<T> selectByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);
T selectOne(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
Integer selectCount(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
List<T> selectList(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
List<Map<String, Object>> selectMaps(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
List<Object> selectObjs(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
<E extends IPage<T>> E selectPage(E page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
<E extends IPage<Map<String, Object>>> E selectMapsPage(E page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
}
链式查询
@Test
void contextLoads() {
QueryWrapper<Employee> wrapper = new QueryWrapper<Employee>()
.like("last_name", "b")
.eq("age", 30)
.eq("gender", 1);
employeeMapper.delete(wrapper);
}
只查询部分字段
https://blog.csdn.net/qq_38232816/article/details/109283507
entity dto vo 互转
https://www.codedemo.club/entity-to-and-from-dto-for-a-java-spring-application/
实体Post向数据传输对象PostDto的转换过程
private PostDto convertToDto(Post post) {
PostDto postDto = modelMapper.map(post, PostDto.class);
return postDto;
}
数据传输对象PostDto像实体Post的转换过程
private Post convertToEntity(PostDto postDto) throws ParseException {
Post post = modelMapper.map(postDto, Post.class);
return post;
}
链式操作
LambdaUpdateWrapper
LambdaUpdateWrapper<Course> luw = new LambdaUpdateWrapper<Course>();
luw.set(Course::getTeacherId, StpUtil.getLoginIdAsInt())
.set(Course::getId, id)
.set(Course::getLogicDelete, 1);
boolean b = courseService.update(luw);
UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
updateWrapper.lambda()
.le(User::getAge, 30)
.setSql("email = '[email protected]'");
userService.update(updateWrapper);
Shiro
专业术语
shiro笔记:https://blog.csdn.net/A233666/article/details/113436397
跟我学shiro:https://www.w3cschool.cn/shiro/co4m1if2.html
authenticator:认证(器) (authentic:真正的)
authorizer:授权(器) (authorize:授权)
principals: 身份信息
credentials: 证明/凭证信息
Shiro 默认提供的 Realm
以后自定义realm一般继承 AuthorizingRealm(授权)即可;其继承了 AuthenticatingRealm(即身份验证),而且也间接继承了 CachingRealm(带有缓存实现)。
自定义Realm需要继承AuthorizingRealm并实现两个方法
通过分析源码可得:
认证:
1.最终执行用户名比较是 在SimpleAccountRealm(简单账户的realm)类 的 doGetAuthenticationInfo 方法中完成用户名校验
2.最终密码校验是在 AuthenticatingRealm类 的 assertCredentialsMatch方法 中
总结:
AuthenticatingRealm 认证realm doGetAuthenticationInfo
AuthorizingRealm 授权realm doGetAuthorizationInfo