微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Redis和Mysql的增删改查

RedisMysqL的增删改查

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐