SpringBoot框架学习(十四)——整合Redis

十八、SpringBoot与Redis

代码已上传至github:https://github.com/2NaCl/redis-demo

1. Redis简介

Redis是一个开源的,内存中的数据结构存储系统,可以用作数据库、缓存和消息中间件。

2. Redis基础操作演示

<1>首先导入依赖,引入Jedis客户端所需要的库

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

<2>同时在yml中对Redis进行配置

spring:
	redis:
	    host: 127.0.0.1
	    port: 6379

<3>引入Redis的自动配置

找到RedisConfiguration的两个Bean然后调用出来
在这里插入图片描述

@Autowired
    StringRedisTemplate stringRedisTemplate; #操作string

    @Autowired
    RedisTemplate redisTemplate; #操作kv都是对象的

<4>使用stringRedisTemplate操作redis

/**
     * String(字符串) List(列表) Set(集合) Hash(散列) ZSet(有序集合)
     *
     * stringRedisTemplate.opsForValue()[String]
     * stringRedisTemplate.opsForHash()[List]
     * stringRedisTemplate.opsForSet()[Set]
     * stringRedisTemplate.opsForHash()[Hash]
     * stringRedisTemplate.opsForZSet()[ZSet]
     */
    @Test
    public void test(){
        //给redis中保存一个数据
        stringRedisTemplate.opsForValue().append("msg", "Hello");
        //检测redis一个数据
        String msg = stringRedisTemplate.opsForValue().get("msg");
        System.out.println(msg);

		//添加一个列表
        stringRedisTemplate.opsForList().leftPush("mylist", "1");
        stringRedisTemplate.opsForList().leftPush("mylist", "2");
    }

<5>使用redisTemplate将数据以对象的形式存储进入redis

首先我们先用比较耿直的方法存储进入redis

@Test
    public void test2(){
        Employee empById = employeeMapper.getEmpById(1);
        //默认如果保存对象,使用jdk序列化机制,序列化后的数据保存在redis中
        redisTemplate.opsForValue().set("emp01",empById);
    }

运行之后查询发现全是序列化之后的乱码,而我们一般存储数据一般都是json格式,所以我们要用工具将其转换成为json
在这里插入图片描述

<6>使用redisTemplate将数据以json对象的形式存储进入redis

RedisConfiguration内会有相关的配置,拿过来做一定的修改即可

@Bean
    public RedisTemplate<Object, Employee> empRedisTemplate(
            RedisConnectionFactory redisConnectionFactory
    )throws UnknownException {
        RedisTemplate<Object, Employee> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory);
        Jackson2JsonRedisSerializer<Employee> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Employee>(Employee.class);
        template.setDefaultSerializer(jackson2JsonRedisSerializer);
        return template;
    }

然后注入配置,使用@Autowired,重新opsForValue数据

@Test
    public void test2(){
        Employee empById = employeeMapper.getEmpById(1);
        //默认如果保存对象,使用jdk序列化机制,序列化后的数据保存在redis中
//        redisTemplate.opsForValue().set("emp01",empById);
        //1.将数据以json方式进行保存
        //(1)自己将对象转为json
        //(2)redisTemplate默认的序列化规则
        empRedisTemplate.opsForValue().set("emp01",empById);

    }

重新运行查看数据即可

在这里插入图片描述
在这里插入图片描述
并且也可以发现重新查询并不会再查询数据库,而是查询缓存。

然后基本的操作也就到这里了。

下面说说Redis的核心作用:缓存

3. SpringBoot结合Redis操作缓存

在之前的SpringBoot框架学习中呢,学习了一下SpringBoot内置的管理器,也就是CacheManager,使用缓存组件给缓存进行crud操作 。

并且因为我们之前已经启动了Redis的Configuration,所以默认生效的Cache[SimpleCacheConfiguiration]也就失效了,而原因就是因为我们引入了redis的starter。

RedisCacheManager帮助我们创建RedisCache来作为缓存组件;RedisCache通过操作缓存数据库来控制缓存。

而虽然帮助我们存储了缓存,但是缓存实际上还是以kv格式存入在mysql还是以序列化的格式存储的,所以我们要多一步转换成json的操作。

操作方法:

  1. 首先要有starter的依赖,让默认缓存Manager是Redis在生效的

<1>基于注解的形式操作缓存

  1. 默认操作的RedisCacheManager操作redis的时候使用的是RedisTemplate<Object,Object>,这不符合我们需要的配置,所以我们需要自定义RedisCacheManager
 //cacheManagerCustomizers可以来定制缓存的一些规则
    @Bean
    public RedisCacheManager redisCacheManager(RedisTemplate<Object, Employee> empRedisTemplate) {
        RedisCacheManager cacheManager = new RedisCacheManager(empRedisTemplate);
        //key多了一个前缀

        //使用前缀默认会将CacheName作为key的前缀
        cacheManager.setUsePrefix(true);
        return cacheManager;
    }

但是如果我们这样配置查询缓存的机制是一定会出问题的。
现在不查这个表了,换其他表试试查询:

在这里插入图片描述
这是第一遍的正常查询,然后第二次查询,按理来说会触发缓存机制:

在这里插入图片描述

但是报错了,报错内容一目了然,是因为我们在Redis的缓存配置中,标注了一个固定的表,所以会出现json转换的问题,那么我们就要对配置进行一个复制和修改。

@Bean
    public RedisTemplate<Object, Department> deptRedisTemplate(
            RedisConnectionFactory redisConnectionFactory
    )throws UnknownException {
        RedisTemplate<Object, Department> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory);
        Jackson2JsonRedisSerializer<Department> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Department>(Department.class);
        template.setDefaultSerializer(jackson2JsonRedisSerializer);
        return template;
    }

    //cacheManagerCustomizers可以来定制缓存的一些规则
    @Bean
    public RedisCacheManager deptRedisCacheManager(RedisTemplate<Object, Department> deptRedisTemplate) {
        RedisCacheManager cacheManager = new RedisCacheManager(deptRedisTemplate);
        //key多了一个前缀

        //使用前缀默认会将CacheName作为key的前缀
        cacheManager.setUsePrefix(true);
        return cacheManager;
    }

配置添加完了,然后我们要在Service层配置CacheConfig,让不同的表能匹配到不同的Cache,防止匹配出错误。

@CacheConfig(cacheNames = "dept",cacheManager = "deptRedisCacheManager")

(1)注意,这个注解可以添加在方法上,也可以添加在类上
(2)注意,配置多个CacheManager的时候,要在其中一个CacheManager上写上注解@Primary,意思是默认启动的缓存管理器

    @Bean
    @Primary
    public RedisCacheManager redisCacheManager(RedisTemplate<Object, Employee> empRedisTemplate) {

然后重新启动即可,程序是没有问题的。

以上使我们使用注解的方式来配置缓存,不过也可以使用代码的方式来配置缓存。

<2>基于Java代码的形式操作缓存

首先来到Service层,我们之前是使用注解:
在这里插入图片描述
来匹配我们写好的缓存配置,但是现在也可以使用这个方法:

@Service
public class DeptService {

    @Autowired
    DepartmentMapper departmentMapper;

    @Qualifier("redisCacheManager") //标记缓存管理器的id
    @Autowired
    RedisCacheManager redisCacheManager;

    //使用缓存管理器得到缓存操作
    public Department getDeptId(Integer id) {
        System.out.println("check successful"+id);
        Department department = departmentMapper.getDeptById(id);

        //获取缓存
        Cache dept = redisCacheManager.getCache("dept");
        //操作缓存
        dept.put("dept:1",department);
        return department;
    }

}

重新运行代码也可以得到相同的效果.

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要实现Spring Boot整合Redis和MySQL,并将数据从MySQL导入Redis,可以按照以下步骤进行: 1. 在pom.xml文件中添加Redis和MySQL的依赖。 2. 在application.properties文件中配置Redis和MySQL的连接信息。 3. 创建一个RedisConfig类,用于配置RedisTemplate。 4. 创建一个MySQLConfig类,用于配置DataSource和JdbcTemplate。 5. 创建一个Service类,用于从MySQL中读取数据,并将数据存储到Redis中。 6. 在Controller中调用Service类中的方法,从Redis中读取数据并返回给前端。 下面是一个简单的示例代码: 1. pom.xml文件中添加Redis和MySQL的依赖: ``` <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> ``` 2. application.properties文件中配置Redis和MySQL的连接信息: ``` # Redis spring.redis.host=localhost spring.redis.port=6379 # MySQL spring.datasource.url=jdbc:mysql://localhost:3306/test spring.datasource.username=root spring.datasource.password=root ``` 3. 创建一个RedisConfig类,用于配置RedisTemplate: ``` @Configuration public class RedisConfig { @Bean public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) { RedisTemplate<String, Object> template = new RedisTemplate<>(); template.setConnectionFactory(factory); template.setKeySerializer(new StringRedisSerializer()); template.setValueSerializer(new GenericJackson2JsonRedisSerializer()); return template; } } ``` 4. 创建一个MySQLConfig类,用于配置DataSource和JdbcTemplate: ``` @Configuration public class MySQLConfig { @Bean @ConfigurationProperties(prefix = "spring.datasource") public DataSource dataSource() { return DataSourceBuilder.create().build(); } @Bean public JdbcTemplate jdbcTemplate(DataSource dataSource) { return new JdbcTemplate(dataSource); } } ``` 5. 创建一个Service类,用于从MySQL中读取数据,并将数据存储到Redis中: ``` @Service public class UserService { private final JdbcTemplate jdbcTemplate; private final RedisTemplate<String, Object> redisTemplate; public UserService(JdbcTemplate jdbcTemplate, RedisTemplate<String, Object> redisTemplate) { this.jdbcTemplate = jdbcTemplate; this.redisTemplate = redisTemplate; } public List<User> getAllUsers() { List<User> users = jdbcTemplate.query("SELECT * FROM user", new BeanPropertyRowMapper<>(User.class)); users.forEach(user -> redisTemplate.opsForValue().set("user:" + user.getId(), user)); return users; } } ``` 6. 在Controller中调用Service类中的方法,从Redis中读取数据并返回给前端: ``` @RestController public class UserController { private final UserService userService; public UserController(UserService userService) { this.userService = userService; } @GetMapping("/users") public List<User> getAllUsers() { List<User> users = (List<User>) userService.redisTemplate.opsForValue().get("users"); if (users == null) { users = userService.getAllUsers(); userService.redisTemplate.opsForValue().set("users", users); } return users; } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值