基于Restful风格实现下列接口:
今天我们继续昨天的课程来学习一下MybatisPlus的核心功能——IService接口
下面是我们需要在pom文件中要引入的依赖
<!--swagger-->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-openapi2-spring-boot-starter</artifactId>
<version>4.1.0</version>
</dependency>
<!--web-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
下面先展示一下代码:
@Api(tags = "用户管理接口")
@RequestMapping("/users")
@RestController
@RequiredArgsConstructor//只对一开始需要做初始化的变量进行构造
public class UserController {
private final IUserService userService;
@ApiOperation("新增用户接口")
@PostMapping
public void saveUser(@RequestBody UserFormDTO userFormDTO){
//1.把DTO拷贝到PO
User user = BeanUtil.copyProperties(userFormDTO, User.class);
//2.新增
userService.save(user);
}
@ApiOperation("删除用户接口")
@DeleteMapping("{id}")
public void deleteUserById(@ApiParam("用户id")@PathVariable("id") Long id){//@PathVariable注解声明路径用id来进行占位
userService.removeById(id);
}
@ApiOperation("根据id查询用户接口")
@GetMapping("{id}")
public UserVO queryUserById(@ApiParam("用户id")@PathVariable("id") Long id) {
//1.查询用户
User user = userService.getById(id);
//2.把PO拷贝到VO
return BeanUtil.copyProperties(user, UserVO.class);
}
@ApiOperation("根据id批量查询用户接口")
@GetMapping("{id}")
public List<UserVO> queryUserByIds(@ApiParam("用户id集合")@RequestParam("id") List<Long> ids) {
//1.查询用户
List<User> users = userService.listByIds(ids);
//2.把PO拷贝到VO
return BeanUtil.copyToList(users, UserVO.class);
}
}
我们要利用好MybatisPlus给我们提供的各种方法来进行便捷开发,这样写可以不用写一条service语句就可以实现功能。
学到的东西:1.@RequireArgsConstructor注解是用于对一开始需要初始化变量进行构造的注解,我们在controller层写接口方法时要先声明出对应的service层,但是spring建议我们使用构造方法来声明,就要加上这个注解。或者我们不愿意这样的话依旧可以privite然后再加上@Autowired注解即可
2.在两个实体类需要转换时可以使用到hutool包下的copyProperties方法,括号里穿的参数是要转换的数据,要转换成的数据.class。如果是批量转化则用同一个包下的copyToList方法,括号里传的参数一样。
3.@RequestBody主要用来接受前端给后端传过来的json数据,大多用在post请求中
4.@PathVariable("id") 注解将 URL 中的 {id} 部分绑定到 userId 参数上
接下来我们实现扣除余额功能:首先看代码
Controller层:
@ApiOperation("扣减用户余额")
@PutMapping("/{id}/deduction/{money}")
public void deductMondyById(@ApiParam("用户id")@PathVariable("id") Long id,
@ApiParam("扣减的金额")@PathVariable("money") Integer money){//@PathVariable注解声明路径用id来进行占位
userService.deductBalance(id,money);
}
Service层:
void deductBalance(Long id, Integer money);
Mapper层:
List<User> queryUserByIds(@Param("ids") List<Long> ids);
void updateBalanceByIds(@Param(Constants.WRAPPER) UpdateWrapper<User> wrapper, @Param("amount") int amount);
@Update("UPDATE tb_user SET balance = balance - #{moeny} Where id = #{id}")
void deductBalance(@Param("id")Long id, @Param("money")Integer money);
实现类:
@Override
public void deductBalance(Long id, Integer money) {
//1.查询用户
User user = this.getById(id);//自己就是userservice所以不用注入,直接调自己即可
//2.校验用户状态
if (user == null || user.getStatus() == 2){
throw new RuntimeException("用户状态异常");
}
//3.校验余额是否充足
if (user.getBalance() < money){
throw new RuntimeException("用户余额不足");
}
//4.扣减金额 update tb_user set balance = balance -?
baseMapper.deductBalance(id,money);
}
在Controller层定义好接口,由于是更新用,要传入两个占位符一个id一个money,在对应的Service层和Mapper层生成好对应的方法,此时我们可以选择在Mapper层的方法上方通过@Update注解来写出我们定义好的sql语句,例如:
@Update("UPDATE tb_user SET balance = balance - #{moeny} Where id = #{id}")
同时在实现类中查询到信息来进行条件判断再对金额进行扣减更新。注:我们在进行条件判断是要进行反向判断以免出现if的嵌套。如我们不希望用户状态异常或者余额不足,我们就要判断这个条件然后再抛出异常。
我们可以登录swagger来进行测试,网址是:http://localhost:8080/doc.htm
下面是我测试的图片:
新增:
批量查询
扣除余额: