Spring Boot实战|缓存机制(二)

《JavaEE开发的颠覆者: Spring Boot实战》系列读书笔记

Spring boot的缓存机制


@Cacheable、@CachePut、@CacheEvit都有value属性,指定的是要使用的缓存名称;key属性指定的是 数据在缓存中的存储的键。
开启声名式缓存支持十分简单,只需在配置类上使用@EnableCaching注解即可。
在Spring Boot环境下,使用缓存技术只需在项目中导入相关缓存技术的依赖包,并在配置类使用@EnableCaching开启缓存支持即可。

使用JPA对mysql进行缓存操作。

添加maven依赖

  • 主要是需要加入jpa和mysql。

    <dependency>
    			<groupId>org.springframework.boot</groupId>
    			<artifactId>spring-boot-starter-data-jpa</artifactId>
    		</dependency>
    
    		<dependency>
    			<groupId>mysql</groupId>
    			<artifactId>mysql-connector-java</artifactId>
    			<version>8.0.16</version>
    		</dependency>
    
  • 配置mysql和jpa

    spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
    spring.datasource.url=jdbc:mysql://127.0.0.1:3306/XX?\
      useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&failOverReadOnly=false
    spring.datasource.username=XX
    spring.datasource.password=XX
    mybatis.configuration.map-underscore-to-camel-case=true
    server.port=8080
    

server层

/**
     * /@CachePut缓存新增的或更新的数据到缓存,其中缓存名称为cityinfocache,数据的key是cityInfo的id。
     * @param cityInfo
     * @return
     */
    @Override
    @Cacheable(value = "cityinfocache",key="#cityInfo.id")
    public CityInfo saveCity(CityInfo cityInfo) {
        cityRepository.save(cityInfo);
        log.info("为" + cityInfo.getId() + "数据做了缓存");
        return cityInfo;
    }

    /**
     * //@CacheEvict从缓存cityInfo中删除key为id的数据。
     * @param id
     */
    @Override
    @CacheEvict(value = "cityinfocache")
    public void remove(int id) {
        log.info("删除了" + id + "数据缓存");
        cityRepository.deleteById(id);
    }

controller层

/**
     * 结合mysql,测试多次查询是否重复调用方法
     * @return
     */
    @RequestMapping(value = "savedb")
    public Result<CityInfo> SaveDb(@RequestBody CityInfo cityInfo) {
        CityInfo info = cityInfoDbService.saveCity(cityInfo);
        return new Result<CityInfo>(info);
    }

    /**
     * 结合mysql,测试删除
     * @return
     */
    @RequestMapping(value = "deletedb/{key}")
    public Result<CityInfo> DeleteDb(@PathVariable("key") int key) {
        CityInfo info = new CityInfo();
        cityInfoDbService.remove(key);
        return new Result<CityInfo>(info);
    }

当被缓存的数据被更新的时候,可以使用@CacheEvict来清除缓存,则可以保证缓存的数据是最新的

redis简介

  • redis是一种NOSQL数据库(非关系型的数据库),一个开源的,先进的 key-value存储可用于构建高性能的存储解决方案。它支持数据结构有字符串,哈希,列表,集合等丰富的数据类型。
  • 在 Spring Boot 中,默认集成的Redis 就是 Spring Data Redis,默认底层的连接池使用了 lettuce ,开发者可以自行修改为自己的熟悉的,例如 Jedis。

添加redis,使用Mysql+redis进行操作。

添加maven依赖

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

添加配置

spring.redis.database=0
spring.redis.host=127.0.0.1
spring.redis.port=6379
spring.redis.password=
spring.redis.pool.max-active=8
spring.redis.pool.max-wait=-1
spring.redis.pool.max-idle=8
spring.redis.pool.min-idle=0
spring.redis.timeout=5000

Redis缓存配置

@Configuration
@EnableCaching//启用缓存
public class RedisConfig extends CachingConfigurerSupport{

    /**
     * 注入 RedisConnectionFactory
     */
    @Autowired
    RedisConnectionFactory redisConnectionFactory;

    /**
     * 实例化 RedisTemplate 对象
     *
     * @return
     */
    @Bean
    public RedisTemplate<String, Object> functionDomainRedisTemplate() {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        initDomainRedisTemplate(redisTemplate, redisConnectionFactory);
        return redisTemplate;
    }

    /**
     * 设置数据存入 redis 的序列化方式
     *
     * @param redisTemplate
     * @param factory
     */
    private void initDomainRedisTemplate(RedisTemplate<String, Object> redisTemplate, RedisConnectionFactory factory) {
        //定义key生成策略
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashValueSerializer(new JdkSerializationRedisSerializer());
        redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer());
        redisTemplate.setConnectionFactory(factory);
    }

    /**
     * 缓存管理器
     * @param redisTemplate
     * @return
     */
    @Bean
    public CacheManager cacheManager(RedisTemplate<?,?> redisTemplate) {
           CacheManager cacheManager = new RedisCacheManager(redisTemplate);
           return cacheManager;
    }

    /**
     * 实例化 HashOperations 对象,可以使用 Hash 类型操作
     *
     * @param redisTemplate
     * @return
     */
    @Bean
    public HashOperations<String, String, Object> hashOperations(RedisTemplate<String, Object> redisTemplate) {
        return redisTemplate.opsForHash();
    }

    /**
     * 实例化 ValueOperations 对象,可以使用 String 操作
     *
     * @param redisTemplate
     * @return
     */
    @Bean
    public ValueOperations<String, Object> valueOperations(RedisTemplate<String, Object> redisTemplate) {
        return redisTemplate.opsForValue();
    }

    /**
     * 实例化 ListOperations 对象,可以使用 List 操作
     *
     * @param redisTemplate
     * @return
     */
    @Bean
    public ListOperations<String, Object> listOperations(RedisTemplate<String, Object> redisTemplate) {
        return redisTemplate.opsForList();
    }

    /**
     * 实例化 SetOperations 对象,可以使用 Set 操作
     *
     * @param redisTemplate
     * @return
     */
    @Bean
    public SetOperations<String, Object> setOperations(RedisTemplate<String, Object> redisTemplate) {
        return redisTemplate.opsForSet();
    }

    /**
     * 实例化 ZSetOperations 对象,可以使用 ZSet 操作
     *
     * @param redisTemplate
     * @return
     */
    @Bean
    public ZSetOperations<String, Object> zSetOperations(RedisTemplate<String, Object> redisTemplate) {
        return redisTemplate.opsForZSet();
    }

}

创建实体类,注意实现Serializable序列化:

@Entity
@Table(name="city")
public class CityInfo implements Serializable {
    private static final long serialVersionUID = 2845294956907027149L;

    private String redisKey;
    //redis中的key

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;
    private String city;

    public CityInfo() {

    }

    public CityInfo(int id, String city) {
        this.id = id;
        this.city = city;
    }

    public int getId() {
        return id;
    }

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

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public String getRedisKey() {
        return redisKey;
    }

    public void setRedisKey(String redisKey) {
        this.redisKey = redisKey;
    }
}

定义JPA接口:

@Repository
public interface CityRepository extends JpaRepository<CityInfo,Integer> {
}

定义Service层

/**
     * 根据Id查询城市信息
     * @param id
     * @return
     */
    public CityInfo findById(Integer id);

    /**
     * 查询所有城市信息
     * @return
     */
    public List<CityInfo> findAll();

    /**
     * 添加或修改城市信息
     * @param user
     */
    public void save(CityInfo user);

    /**
     * 根据Id删除城市信息
     * @param id
     */
    public void delete(Integer id);

定义Service接口实现类ServiceImpl,在需要缓存的接口上添加注解

//allEntries 清空缓存所有属性 确保更新后缓存刷新
    @CacheEvict(value="cityCache", allEntries=true)
    @Override
    public void save(CityInfo cityInfo) {
        // TODO Auto-generated method stub
        cityRepository.save(cityInfo);
        if(cityInfo.getRedisKey()==null||"".equals(cityInfo.getRedisKey().trim())){
            cityInfo.setRedisKey(String.valueOf(cityInfo.getId()));
            cityRepository.save(cityInfo);
        }
        cityRedisService.put(cityInfo.getRedisKey(), cityInfo, -1);
    }

    //allEntries 清空缓存所有属性 确保更新后缓存刷新
    @CacheEvict(value="cityCache", allEntries=true)
    @Override
    public void delete(Integer id) {
        // TODO Auto-generated method stub
        CityInfo cityInfo=cityRepository.findById(id).get();
        cityRedisService.remove(cityInfo.getRedisKey());
        cityRepository.deleteById(id);
    }

controller层

 /**
     * 查询所有城市信息  redis
     * @return
     */
    @RequestMapping("/findAll")
    public List<CityInfo> findAll(){
        return cityInfoRdService.findAll();
    }

参考文档

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值