Redis

【Redis】redis缓存的实现

2019-06-26  本文已影响0人  扮鬼之梦

redis缓存的原理

1.查询数据时,首先根据接口名称和请求参数查询redis缓存,查到了对应数据的话,直接返回结果
2.redis未查询到,就查询数据库
3.数据库查询到数据的话,就存入缓存并返回结果
4.第二次查询的话,就有第一次存入redis的数据,会直接查询redis,然后返回结果

缓存的大致实现

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.thy.pojo.User;
import com.thy.util.RedisUtils;

@RestController
@RequestMapping("/user")
public class UserController {
    @Autowired
    private RedisUtils redisUtils;
    
    @RequestMapping("/queryUserById")
    public Object queryUserById(Integer id) {
        //1.查询redis缓存,查到了直接返回结果
        User user = (User) redisUtils.get("user/queryUserById/"+id);
        if(user!=null) {
            return user;
        }
        
        //2.redis未查询到,就查询数据库(这里模拟查询数据库会花比较久的时间)
        try {
            Thread.sleep(5000);
            user = new User(id, "郭南林", 24, "男");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        
        //3.数据库查询到数据就存入缓存
        if(user!=null) {
            redisUtils.set("user/queryUserById/"+id, user);
        }
        
        //4.返回数据库查询结果
        return user;
    }

}

接口访问结果

第一次访问时返回数据的时间大致为5s(查询的数据库),之后使用同样的访问参数访问,很快就可以得到返回数据(访问的redis),这里就实现了简单的redis缓存。


访问结果
redis中相应的缓存数据

Redis注解开发

添加依赖

<dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-cache</artifactId>
</dependency>

使用缓存

1.启动类中添加注解

@EnableCaching

2.需要缓存的类上添加

@CacheConfig

3.方法上添加

//添加缓存
@Cacheable
//修改缓存
@CachePut
//删除缓存
@CacheEvict

例子

import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import com.thy.pojo.User;
import com.thy.service.UserService;
@Service
@CacheConfig
public class UserServiceImpl implements UserService{

    /**
     * cacheNames可写多个,若缓存中存在其中任意一个,就返回缓存中的值
     */
    @Cacheable(cacheNames= {"userService.queryUserByName"})
    @Override
    public User queryUserByName(Integer id,String name) {
        User user = null;
        try {
            Thread.sleep(2000);
            user = new User(id, name, 24, "男");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return user;
    }
    
    /**
     * 自定义key,若不填写key,则默认的key值为#user.toString()
     */
    @Cacheable(cacheNames= {"userService.queryUser"},key="#user.id")
    @Override
    public User queryUser(User user) {
        User user2 = null;
        try {
            Thread.sleep(2000);
            user2 = new User(user.getId(), user.getName(), 24, "男");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return user2;
    }
    /**
     * 更新缓存,先更改,再将返回值存入缓存
     */
    @CachePut(cacheNames= {"userService.queryUser"},key="#user.id")
    @Override
    public User updateUser(User user) {
        //先修改数据库
        try {
            //模拟修改数据库
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //将修改后的对象返回
        return user;
    }

    /**
     * @CacheEvict 的属性allEntries为true时,忽略传入的参数,删除cacheNames中所有的缓存,为false(默认)时,根据cacheNames+key来删除缓存。
     * @CacheEvict 的属性beforeInvocation为true时,在调用方法前清除,为false(默认)时方法执行成功之后清除
     */
    @CacheEvict(cacheNames= {"userService.queryUser"},key="#id")
    @Override
    public int deleteUser(Integer id) {
        //根据id删除User
        return 1;
    }

}

注意:返回的对象需要实现序列化和toString方法,在此例中为User对象,不然有些地方会报错

demo地址

https://gitee.com/gnliscream/redis-cache-demo.git

上一篇下一篇

猜你喜欢

热点阅读