Redis缓存

Redis缓存技术学习一

缓存需要注意的几点

  • 缓存穿透:当我们查询数据时候,数据库中没有我们查询的数据,而且缓存中也没有
    解决:在缓存中存储当前数据主键的最大值 (自增),把所有主键的值放入缓存中
  • 缓存雪崩:缓存中大量的数据在极短的时间到期
    解决:让数据一部分一部分的到期
    缓存穿刺:大量的请求访问数据库, 解决:加锁
  1. 导入依赖包
		
            redis.clients
            jedis
            2.9.0
        `

2.添加配置文件

redis:
    host: 10.9.251.200
    port: 8100
    password: //密码
    jedis:
      pool:
        min-idle: 10
        max-idle: 100
        max-active: 1024

3.创建对象

/**
 * Redis配置类
 */
@Configuration
public class RedisConfig {

    //使用注解加载配置文件的内容
    @Value("${spring.redis.host}")
    private String host;
    @Value("${spring.redis.port}")
    private int port;
    @Value("${spring.redis.password}")
    private String password;

    @Bean
    public JedisPool jedisPool(JedisPoolConfig jedisPoolConfig) {
        JedisPool jedisPool = new JedisPool(jedisPoolConfig, host, port, 5000, password);
        return jedisPool;
    }

    @Bean
    public JedisPoolConfig jedisPoolConfig() {
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        //设置config的属性
        jedisPoolConfig.setMaxTotal(1024);
        jedisPoolConfig.setMaxIdle(100);
        jedisPoolConfig.setMinIdle(10);
        return jedisPoolConfig;
    }

}

4.编写缓存工具类,将数据存放入缓存中

public class RedisUtils {

    public static void hset(String key, Notice notice, Jedis jedis) throws IntrospectionException, InvocationTargetException, IllegalAccessException {

        Class aClass = notice.getClass();
        //获得实体类中的各个属性
        Field[] declaredFields = aClass.getDeclaredFields();
        //进行遍历
        for (Field declaredField : declaredFields) {
            //获得属性的名称
            String name = declaredField.getName();
            //PropertyDescriptor作用就是获得属性的get和set方法,参数为属性名和类的对象
            PropertyDescriptor propertyDescriptor = new PropertyDescriptor(name, aClass);
            //不为空说明方法存在
            if (propertyDescriptor != null) {
                //getReadMethod  获取属性的get方法
                Method readMethod = propertyDescriptor.getReadMethod();
                //得到结果
                Object result = readMethod.invoke(notice);

                if (result != null) {
                    //调用jedis的方法,加入缓存
                    jedis.hset(key, name, result.toString());
                }
            }
        }
    }
}

4.使用缓存,首先查看缓存中是否有我们需要的数据 如果没有查询数据库

/**
     * 查询详情
     * @param notice_id
     * @param user_id
     * @return
     */
    @Override
    public ResultBean getDetail(int notice_id, int user_id) {
        Jedis jedis = null;
        try {
            //从缓存池中获取 缓存对象
            jedis = jedisPool.getResource();
            //先从缓存中查询  规定key为 notice_id:id user_id:id
            String key = "notice" + notice_id + "user" + user_id;
            //查看缓存中是否是需要的数据
            Map map = jedis.hgetAll(key);

            if (map == null || map.isEmpty()) {
                //放穿透---查询数据库中时候有该数据的id值
                Boolean fangchuntou = jedis.sismember("fangchuantou_jll", String.valueOf(notice_id));
                //如果数据库有该数据,查询数据库
                if (fangchuntou) {
                    //从数据库中查询
                    Notice notice = noticeMapper.findNoticeByNotice_idAndUser_id(notice_id, user_id);

                    if (notice != null) {
                        //调用工具类,放入缓存
                        RedisUtils.hset(key, notice, jedis);
                        //设置有效期
                        jedis.expire(key, 1800);

                        return ResultBean.setOK(notice);
                    }
                }

            }else {
                ResultBean.setOK(map);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (jedis != null) {
                jedis.close();
            }
        }
        return ResultBean.setERROR("没有此商品");
    }
}

5.防穿透的设置,服务器开启之前将数据库中数据的id存入缓存中

	 @PostConstruct
    public void init() {
        Jedis jedis = jedisPool.getResource();
        //查询数据库id
        List ids = noticeMapper.findNoticeAllId();
        
        jedis.sadd("fangchuantou_jll", ids.toArray().toString());
        jedis.close();
    }

你可能感兴趣的:(springboot)