springboot系列文章(十一)springboot整合redis

redis估计都不陌生了吧,如果不知道的可以去看我以前的文章进行查看,今天我们看看springboot使用redis最为缓存是如何使用的

ok直接看代码,具体细节代码中讲授一二

1.引入pom.xml。前提说下这里使用的mybatis的文件是这样的:

<dependency>   
    <groupId>org.mybatis.spring.boot</groupId>    
    <artifactId>mybatis-spring-boot-starter</artifactId>   
    <version>2.0.1</version>
</dependency>

如果这里是高版本的当我们自定义配置cache的方式就不是本文章所看到的那样了

2.spring.application的配置文件

spring.datasource.url=jdbc:mysql://localhost:3306/spring-boot-cache?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
spring.datasource.password=123
spring.datasource.username=root
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
#开启驼峰mybatis.configuration.map-underscore-to-camel-case=trues
pring.redis.host=127.0.0.1

3.redis的配置类:

package com.kayleoi.springbootcache.config;
​
import com.kayleoi.springbootcache.bean.Department;
import com.kayleoi.springbootcache.bean.Employee;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.ResourceLoader;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
​
import java.net.UnknownHostException;
import java.util.LinkedHashSet;
import java.util.List;
​
/**
 * @Author kay三石
 * @date:2019/8/3
 * 当有多个缓存管理器时,必须指定一个默认的缓存管理器
 *     @Primary 指定默认的缓存管理器,这里我们话应该使用spring中自带的(不加会出现以下错误)
 *     java.lang.IllegalStateException: No CacheResolver specified, and no unique bean of type CacheManager found.
 *     Mark one as primary or declare a specific CacheManager to use.
 *需要使用低版本的对于2.0.0以上的版本使用方法不是这样的
 */
@Configuration
public class MyRedisConfig {
    /**
     * 用自己的CacheManager 为 employee序列化缓存
     *@Primary 将某个缓存管理器设为默认的
     * @param
     * @return
     */
    @Bean
    public RedisCacheManager employeeCacheManager(RedisTemplate<Object,Employee> empRedisTemplate) {
        RedisCacheManager cacheManager = new RedisCacheManager(empRedisTemplate);
        //key 使用前缀,将CacheName最为前缀
        cacheManager.setUsePrefix(true);
        return cacheManager;
    }
    /**
     * 用自己的CacheManager 为 depart序列化缓存管理器
     * @param
     * @return
     */
    @Bean
    public RedisCacheManager departmentCacheManager(RedisTemplate<Object,Department> depRedisTemplate) {
        RedisCacheManager cacheManager = new RedisCacheManager(depRedisTemplate);
        //key 使用前缀,将CacheName最为前缀
        cacheManager.setUsePrefix(true);
        return cacheManager;
    }
​
    /**
     * 使用自己的将object对象转化为json
     * @param redisConnectionFactory
     * @return
     * @throws UnknownHostException
     */
    @Bean
    public RedisTemplate<Object,Employee> empRedisTemplate(
            RedisConnectionFactory redisConnectionFactory)throws UnknownHostException {
        RedisTemplate<Object, Employee> template = new RedisTemplate <>();
        template.setConnectionFactory(redisConnectionFactory);
        template.setDefaultSerializer(new Jackson2JsonRedisSerializer <Employee>(Employee.class));
        return template;
    }
​
    @Bean
    public RedisTemplate<Object, Department> depRedisTemplate(
            RedisConnectionFactory redisConnectionFactory)throws UnknownHostException {
        RedisTemplate<Object, Department> template = new RedisTemplate <>();
        template.setConnectionFactory(redisConnectionFactory);
        template.setDefaultSerializer(new Jackson2JsonRedisSerializer <Department>(Department.class));
        return template;
    }
​
    /**
     * 选择redis作为默认缓存工具
     * @param redisTemplate
     * @return
     */
    @Primary
    @Bean
    public RedisCacheManager cacheManager(RedisTemplate redisTemplate) {
        RedisCacheManager caheManager = new RedisCacheManager(redisTemplate);
        return caheManager;
    }
}
​
/**
 * 默认使用时ConcurrentMapCacheManager == ConcurrentMapCache 将数据保存到ConcurrentMap<Object,Object>
 *  实际开发中使用的是 中间件, redis,ehcache
 *
 *  redis 测试缓存,原理 CacheManager === Cache 将组件来实际给缓存存取数据
 *  引入redis的start后容器所用的是RedisCacheManager
 *  RedisCacheManager 帮我们创建 RedisCache来作为缓存组件
 *  默认保存数据 k,v 都是object 利用序列化转化为json
 *      1.引入redis的start后CacheManager变为 RedisCacheManager
 *      2.默认创建的 RedisCacheManager 操作redis的时候使用的是 RedisTemplate<Object,Object>
 *      3.RedisTemplate<Object, Object>是默认使用jdk的序列化机制
 *   自定义CacheManager:
 *
 */
​
@SpringBootApplication
@MapperScan("com.kayleoi.springbootcache.mapper")
@EnableCaching
public class SpringBootCacheApplication {
​
    public static void main(String[] args) {
        SpringApplication.run(SpringBootCacheApplication.class, args);
    }
​
}
​

service层:

package com.kayleoi.springbootcache.service;
​
import com.kayleoi.springbootcache.bean.Employee;
import com.kayleoi.springbootcache.mapper.EmployeeMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.*;
import org.springframework.stereotype.Service;
​
/**
 * @Author kay三石
 * @date:2019/7/22
 * @CacheConfig(cacheNames = "emp") 抽取缓存的公共配置
 * 原理:
 *  1.自动配置类:CacheAutoConfiguration
 *  2.缓存的配置类:
 *
 *  3.默认的配置类:SimpleCaCheConfiguration
 *  当写了多个cacheManager 的需要指定哪个管理器使用的
 *  当使用了不同的管理器时,需要指定一个默认的缓存管理器,要不然不会找到自己写的缓存管理器
 *
 */
@CacheConfig(cacheNames = "emp", cacheManager = "employeeCacheManager")
@Service
public class EmployeeService {
​
    @Autowired
    EmployeeMapper employeeMapper;
​
    /**
     * 属性:
     * cacheNames/value: 执行缓存组件的名字,将方法的返回结果放到哪个缓存中是数组方式,可指定多个缓存
     * key: 缓存数据使用的key,可以用来指定默认使用方法参数的值,1-方法的返回值
     * 编写spel: # id: 参数id的值, #a0 #p0  #root.args[0]
     * 执行使用的key :key = "#root.methodName+'['+#id+']'" ====getEmployee(id)
     * keyGenerator:key的生成器,可以自己指定key的生成器的组件的id
     * key/keyGenerator二则选一使用
     * <p>
     * cacheManager: 指定缓存管理器,或者cacheResolver指定获取解析器
     * condition: 指定符合条件的情况下才缓存 condion= "#id >0 and #id <10"
     * unless: 否定缓存,当unless指定条件为true时,方法的返回值就不会被缓存,可以获取到结果进行判断
     * unless = "#result == null"
     * unless = "#a0==2" 如果第一个参数为2时则不缓存
     * sync:  是否使用异步的方式
     *
     * @param id
     * @return
     */
    @Cacheable(value = {"emp"}, key = "#root.methodName+'['+#id+']'")
    public Employee getEmployee(Integer id) {
        //用默认的需要序列化
        System.out.println("查询数据库");
        Employee empById = employeeMapper.getEmpById(id);
        return empById;
    }
​
    /**
     * 指定缓存
     *
     * @param id
     * @return
     */
    @Cacheable(value = {"emp2"}, keyGenerator = "myKeyGenerator", condition = "#a0>0", unless = "#a0==2")
    public Employee getEmployee2(Integer id) {
        Employee empById = employeeMapper.getEmpById(id);
        return empById;
    }
​
    /**
     * @CachePut: 调用方法,又更新缓存  ,修改的同时更新(同步更新缓存)
     * 运行实机:
     *  1.先调用目标方法
     *  2.将目标方法的结果缓存起来
     *      方法运行后将结果放入
     *
     * 调式步骤:
     *  1.查询1号员工,查到的结果放入缓存中:
     *      key :1 value: lastName:
     *  2. 以后查询还是之前的结果
     *  3. 更新1号员工,
     *      将方法的返回值放入了缓存 key:传入的emplyee对象,返回的也是对象
     *  4. 查询1号员工
     *      应该是更新后的员工
     *          key = "#employee.id" 使用传入参数的id
     *          key = "#result.id" 使用返回值的id
     * @Caheable的key不能使用#result
     *      但为什么是没有更新前呢?【1号员工没有在缓冲中更新,就是缓存中没有这个key】
     */
    @CachePut(value = {"emp"}, key = "#employee.id")
    public Employee update(Employee employee){
        System.out.println("employee = [" + employee + "]");
        employeeMapper.updateEmp(employee);
        return employee;
​
    }
​
    /**
     * 清除缓存
     *  key:指定清除的数据
     *  allEntries = true 指定清除这缓存中的所有的数据
     *  beforeInvocation = false:
     *          默认是方法执行之后执行,如果出现异常缓存不会清除
     *
     *  beforeInvocation = true
     *          代表清除缓存操作是在方法运行之前执行,无论方法是否出现异常,缓存都清除
     *
     *
     * @param id
     */
    @CacheEvict(value = "emp",beforeInvocation = true, key = "#id")
    public void deleteEmp(Integer id){
        employeeMapper.deleteEmById(id);
    }
    @Caching(
            cacheable = {
                    @Cacheable(value = "emp", key = "#lastName")
            },
            put = {
                    @CachePut(value = "emp", key = "#result.id"),
                    @CachePut(value = "emp", key = "#result.email")
            }
    )
    public Employee getEmployeeByName(String lastName){
        return employeeMapper.getEmpByName(lastName);
    }
}
​

通过以上的配置的代码可以实现redis操作缓存数据。

猜你喜欢

转载自blog.csdn.net/qq_37256896/article/details/100832245
今日推荐