4
2
0
2

Redis和Mysql的增删改查

Redis和Mysql的增删改查

利用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;
    }
}

posted @ 2021-10-19 16:23  CoderTL  阅读(147)  评论(0编辑  收藏  举报