用户空间缓存

用户的使用空间使用频率很高,除了保存在数据库中,还要缓存到Redis中,方便使用。

静态常量,在com.swx.easypan.entity.constants包下的 Constants 类中定义常量

public class Constants {
public static final Integer REDIS_KEY_EXPIRE_ONE_DAY= 60 * 60 * 24;
public static final Integer REDIS_KEY_EXPIRE_ONE_HOUR = 60 * 60;
public static final Integer REDIS_KEY_EXPIRE_FIVE_MIN = 5 * 60;
public static final String REDIS_KEY_USER_SPACE_USE = "easypan:user:spaceuse:";
}

从Redis缓存中获取和保存用户空间信息,在RedisComponent 编写获取和保存方法。

RedisComponent
@Component("redisComponent")
public class RedisComponent {

@Resource
private RedisUtils<Object> redisUtils;

public void saveUserSpaceUse(String userId, UserSpaceDTO userSpaceDto) {
redisUtils.setex(Constants.REDIS_KEY_USER_SPACE_USE + userId, userSpaceDto, Constants.REDIS_KEY_EXPIRE_ONE_DAY);
}

public UserSpaceDTO getUserSpaceUse(String userId) {
return (UserSpaceDTO) redisUtils.get(Constants.REDIS_KEY_USER_SPACE_USE + userId);
}
}

获取用户空间

用户的使用空间会缓存到Redis中,如果Redis中没有则会从数据库查询,查询用户所有的文件大小。

该部分需要先实现查询用户文件大小的接口,其在文件信息工程下。

接口信息

路径地址 http://localhost:7090/api/getUseSpace
请求方式 GET
请求参数
返回结果 UserSpaceDTO

返回结果DTO

在包com.swx.easypan.entity.dto,创建 UserSpaceDTO 实体类,将下面代码放入:

UserSpaceDTO
@Data
public class UserSpaceDTO implements Serializable {
private Long useSpace;
private Long totalSpace;

public UserSpaceDTO() {
}

public UserSpaceDTO(Long useSpace, Long totalSpace) {
this.useSpace = useSpace;
this.totalSpace = totalSpace;
}
}

定义Service

该操作是涉及文件服务和用户服务,新增一层:用户文件服务

新建 UserFileService接口,在其中添加:

UserFileService
public interface UserFileService {

/**
* 获取用户使用空间
*
* @param id 用户ID
*/
UserSpaceDTO getUseSpace(String id);
}

在 UserInfoServiceImpl 中实现该方法

UserFileServiceImpl
@Service
public class UserFileServiceImpl implements UserFileService {

private final RedisComponent redisComponent;
private final FileInfoService fileInfoService;
private final UserInfoService userInfoService;


public UserFileServiceImpl(RedisComponent redisComponent, FileInfoService fileInfoService, UserInfoService userInfoService) {
this.redisComponent = redisComponent;
this.fileInfoService = fileInfoService;
this.userInfoService = userInfoService;
}

/**
* 获取用户使用空间
*
* @param id 用户ID
*/
@Override
public UserSpaceDTO getUseSpace(String id) {
UserSpaceDTO spaceDTO = redisComponent.getUserSpaceUse(id);
if (null == spaceDTO) {
spaceDTO = new UserSpaceDTO();
// 查询当前用户已经上传文件大小总和
Long useSpace = fileInfoService.getUseSpace(id);
UserInfo userInfo = userInfoService.getById(id);
spaceDTO.setUseSpace(useSpace);
spaceDTO.setTotalSpace(userInfo.getTotalSpace());
redisComponent.saveUserSpaceUse(id, spaceDTO);
}
return spaceDTO;
}
}

定义Controller

在 UserInfoController 下定义登陆方法,登陆成功后将用户信息放入到Session中,并将验证码从Session中删除,防止验证码重复使用。

UserInfoController
@RestController("userInfoController")
@ResponseResult
@Validated
public class UserInfoController {

private final UserInfoService userInfoService;

public UserInfoController(UserInfoService userInfoService) {
this.userInfoService = userInfoService;
}

@PostMapping("/login")
public SessionWebUserVO login(HttpSession session,
@Valid @RequestBody LoginDTO loginDto) {
try {
if (!loginDto.getCheckCode().equalsIgnoreCase((String) session.getAttribute(Constants.CHECK_CODE_KEY))) {
throw new BizException("图片验证码错误");
}
SessionWebUserVO sessionWebUserVo = userInfoService.login(loginDto.getEmail(), loginDto.getPassword());
session.setAttribute(Constants.SESSION_KEY, sessionWebUserVo);
return sessionWebUserVo;
} finally {
session.removeAttribute(Constants.CHECK_CODE_KEY);
}
}
}

更新用户空间

定义Mapper

找到 UserInfoMapper,定义更新用户空间的方法

public interface UserInfoMapper extends BaseMapper<UserInfo> {
Integer updateUserSpace(@Param("userId") String userId, @Param("useSpace") Long useSpace, @Param("totalSpace") Long totalSpace);
}

找到 UserInfoMapper.xml,实现更新用户空间的方法,该方法即可更新用户使用空间和用户总空间

UserInfoMapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.swx.easypan.mapper.UserInfoMapper">
<update id="updateUserSpace">
update user_info
<set>
<if test="useSpace!=null">
use_space = use_space + #{useSpace}
</if>
<if test="totalSpace!=null">
total_space = total_space + #{totalSpace}
</if>
</set>
where id = #{userId}
<if test="useSpace!=null">
and <![CDATA[ (use_space + #{useSpace}) <= total_space ]]>
</if>
<if test="totalSpace!=null">
and <![CDATA[ (total_space + #{totalSpace}) >= use_space ]]>
</if>
</update>
</mapper>

定义Service

找到 UserInfoService接口,在其中添加:

UserInfoService
/**
* 更新用户使用空间或者总空间
*
* @param userId 用户ID
* @param useSpace 使用空间
* @param totalSpace 总空间
* @return 是否更新成功
*/
Boolean updateUserSpace(String userId, Long useSpace, Long totalSpace);

在 UserInfoServiceImpl 中实现该方法

UserInfoServiceImpl
@Override
public Boolean updateUserSpace(String userId, Long useSpace, Long totalSpace) {
Integer update = baseMapper.updateUserSpace(userId, useSpace, totalSpace);
return update != null && update >= 1;
}