利用redis缓存
import com.codertl.redis.entities.User; import com.codertl.redis.mapper.UserMapper; import com.codertl.redis.service.UserService; import lombok.extern.slf4j.Slf4j; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.util.concurrent.TimeUnit; @Service @Slf4j public class UserServiceImpl implements UserService { public static final String CACHE_KEY_USER = "user:"; @Resource private UserMapper userMapper; @Resource private RedisTemplate redisTemplate; @Override public void addUser(User user) { // 1. 先插入 mysql 并成功 int i = userMapper.insertSelective(user); if (i > 0) { // 2、需要再次查询一下 mysql 将数据捞回来并ok User queryUser = userMapper.selectByPrimaryKey(user.getId()); // 3、将 查询的 用户存入 redis,完成新增功能的数据一致性 String key = CACHE_KEY_USER + user.getId(); redisTemplate.opsForValue().set(key,queryUser); } } @Override public void deleteUser(Integer id) { int i = userMapper.deleteByPrimaryKey(id); if (i > 0) { String key = CACHE_KEY_USER + id; redisTemplate.delete(key); } } @Override public void updateUser(User user) { int i = userMapper.updateByPrimaryKeySelective(user); if (i > 0) { // 2、需要再次查询一下 mysql 将数据捞回来并ok User queryUser = userMapper.selectByPrimaryKey(user.getId()); // 3、将 查询的 用户存入 redis,完成新增功能的数据一致性 String key = CACHE_KEY_USER + user.getId(); redisTemplate.opsForValue().set(key,queryUser); } } @Override public User findUserById(Integer id) { User user = null; String key = CACHE_KEY_USER + id; // 1、先从 redis 中查询,如果有结果,直接返回,如果没有,再去查询 mysql user = (User) redisTemplate.opsForValue().get(key); if (user == null) { // 2、redis 里面没有,查询Mysql user = userMapper.selectByPrimaryKey(id); if (user == null) { // 3.1、redis + mysql 都没有数据 return user; } else { // 3.2 、mysql中有数据 ,需要将数据写回redis,保证下一次的缓存命中率 redisTemplate.opsForValue().set(key, user); } } return user; } /** * 加强补充,避免key 突然失效了,打爆mysql ,做一下预防,尽量不出现击穿 * @param id * @return */ public User findUserById2(Integer id) { User user = null; String key = CACHE_KEY_USER + id; // 1、先从 redis 中查询,如果有结果,直接返回,如果没有,再去查询 mysql user = (User) redisTemplate.opsForValue().get(key); if (user == null) { // 2、大厂用,对于高 QPS 的优化,进来就先加锁,保证一个请求,让外面的 redis 等待一下,避免击穿mysql synchronized (UserServiceImpl.class) { user = (User) redisTemplate.opsForValue().get(key); // 3、 再次查询redis 还是 null, 就可以去查询 mysql 了(mysql默认有数据) if (user == null) { // 5、redis 里面没有,查询Mysql user = userMapper.selectByPrimaryKey(id); if (user == null) { // 6.1、redis + mysql 都没有数据 return null; } else { // 6.2 、mysql中有数据 ,需要将数据写回redis,保证下一次的缓存命中率 redisTemplate.opsForValue().setIfAbsent(key, user, 7, TimeUnit.DAYS); } } } } return user; } }