springboot使用註解實現redis緩存

在springboot中兩種方式使用緩存,一種是直接通過 RedisTemplate 來使用,另一種是使用 Spring Cache 集成 Redis(也就是註解的方式)。

RedisTemplate 方式不作說明,詳細說明實現一下註解方式。

核心三個註解:

  • @Cachable

  • @CachePut

  • @CacheEvict

1.@Cachable

根據方法的請求參數對其結果進行緩存:

  • Key:緩存的 Key,可以爲空,如果指定要按照 SPEL 表達式編寫,如果不指定,則按照方法的所有參數進行組合。

  • Value:緩存的名稱。

  • Condition:緩存的條件,可以爲空,使用 SPEL 編寫,返回 true 或者 false,只有爲 true 才進行緩存。

寫法:

@Cacheable(value = "user", key = "#id",condition="#id>1")

public User get(Integer id) {

對應關係:

 針對這一句話進行一次比較:根據方法的請求參數對其結果進行緩存。

 @Cacheable(value = "user", key = "#id",condition="#id>1")
    @Override
    public User get(Integer id) {
        logger.info("進入get方法,當前獲取對象:{}", userDao.selectById(id)==null?null:userDao.selectById(id).toString());
        return userDao.selectById(id);
    }

    @Cacheable(value = "test", key = "#id",condition="#id>1")
    @Override
    public String getString(Integer id) {
        logger.info("進入get方法,當前獲取對象:{}", userDao.selectById(id)==null?null:userDao.selectById(id).toString());
        return userDao.selectById(id).getUsername();
    }

一個方法返回的是對象,一個方法返回的是字符串。

redis中存儲結果:一個存的是字符串,一個存的是對象。(沒有進行反序列化處理,大致能看出來不同就行了)

2.@CachePut

根據方法的請求參數對其結果進行緩存:

  • Key:緩存的 Key,可以爲空,如果指定要按照 SPEL 表達式編寫,如果不指定,則按照方法的所有參數進行組合。

  • Value:緩存的名稱。

  • Condition:緩存的條件,可以爲空,使用 SPEL 編寫,返回 true 或者 false,只有爲 true 才進行緩存。

和@Cachable不同的是,@CachePut這個註解可以確保方法被執行,同時方法的返回值也被記錄到緩存中。

@Cacheable當重複使用相同參數調用方法的時候,方法本身不會被調用執行,即方法本身被略過了,取而代之的是方法的結果直接從緩存中找到並返回了。

3.@CacheEvict

根據條件對緩存進行清空:

  • Key:緩存的 Key,可以爲空,如果指定要按照 SPEL 表達式編寫,如果不指定,則按照方法的所有參數進行組合。

  • Value:緩存的名稱。

  • Condition:緩存的條件,可以爲空,使用 SPEL 編寫,返回 true 或者 false,只有爲 true 才進行緩存。

  • allEntries:是否清空所有緩存內容,缺省爲 false,如果指定爲 true,則方法調用後將立即清空所有緩存。

  • beforeInvocation:是否在方法執行前就清空,缺省爲 false,如果指定爲 true,則在方法還沒有執行的時候就清空緩存。缺省情況下,如果方法執行拋出異常,則不會清空緩存。

理論知識結束,實踐一下:

maven依賴:

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

user實體類:這裏必須要序列化,不然進行緩存時會出錯。

public class User implements Serializable {
    private int id;
    private String username;
    private String password;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

}

service和dao跳過,直接貼impl代碼:註解使用都在這裏面

@Service
public class RedisServiceImpl implements IRedisService {

    public static Logger logger = LogManager.getLogger(RedisServiceImpl.class);
    @Autowired
    private UserDao userDao;

    @CachePut(value ="user", key = "#user.id")
    @Override
    public User save(User user) {
        userDao.insert(user);
        logger.info("進入save方法,當前存儲對象:{}", user.toString());
        return user;
    }

    @CacheEvict(value="user", key = "#id")
    @Override
    public void delete(int id) {
        userDao.deleteById(id);
        logger.info("進入delete方法,刪除成功");
    }

    @Cacheable(value = "user", key = "#id",condition="#id>1")
    @Override
    public User get(Integer id) {
        logger.info("進入get方法,當前獲取對象:{}", userDao.selectById(id)==null?null:userDao.selectById(id).toString());
        return userDao.selectById(id);
    }

    @Cacheable(value = "test", key = "#id",condition="#id>1")
    @Override
    public String getString(Integer id) {
        logger.info("進入get方法,當前獲取對象:{}", userDao.selectById(id)==null?null:userDao.selectById(id).toString());
        return userDao.selectById(id).getUsername();
    }
}

最後是controller:使用的mp,不是重點,隨便造點數據即可。

@RestController
@RequestMapping("redis")
public class RedisController {

    public static Logger logger = LogManager.getLogger(RedisController.class);

    @Autowired
    private IRedisService redisService;

    @GetMapping("/add")
    public void add() {
        User user = new User();
        user.setId(3);
        user.setUsername("abc");
        user.setPassword("abc");
        redisService.save(user);
        logger.info("添加的用戶信息:{}", user.toString());
    }

    @GetMapping("/delete")
    public void delete() {
        redisService.delete(3);
    }

    @GetMapping("/get/{id}")
    public void get(@PathVariable("id") String idStr) throws Exception {
        if (StringUtils.isBlank(idStr)) {
            throw new Exception("id爲空");
        }
        Integer id = Integer.parseInt(idStr);
        User user = redisService.get(id);
        logger.info("獲取的用戶信息:{}", user.toString());

    }
    @GetMapping("/getString/{id}")
    public void getString(@PathVariable("id") String idStr) throws Exception {
        if (StringUtils.isBlank(idStr)) {
            throw new Exception("id爲空");
        }
        Integer id = Integer.parseInt(idStr);
        redisService.getString(id);

    }
}

啓動類上必須要開啓註解:

@SpringBootApplication
@EnableCaching
public class ChuanApplication {

    public static void main(String[] args) {
        SpringApplication.run(ChuanApplication.class, args);
    }

}

完成,進行接口測試。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章