 
   
    1.为什么用Spring Data
   
Spring Data 的目标是为数据访问提供一个基于Spring的普遍常用的编程模型,同时仍然保留底层数据存储的特殊特性, 它让使用数据访问技术、关系和非关系数据库和基于云的数据服务变得容易,它包含了很多的子项目例如Spring Data JDBC, Spring Data Redis,Spring Data MongoDB等。
Spring Data Redis是Spring Data项目的一个子项目, 它提供了从Spring应用程序对Redis的简单配置和轻松访问的方法,将开发人员从基础设置问题中解放出来。它消除了存储交互所需啊哟的冗余任务和样板代码,使得编写使用 Redis键值存储的Spring 应用程序变得非常容易
    2.SpringBoot+Redis 示例
   
1. 创建SpringBoot项目,参考目录结构如下
     
   
pom中增加spring-data-redis依赖,参考Pom.xml如下
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.6.3</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.boot</groupId>
    <artifactId>demo-redis</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>demo-redis</name>
    <description>Demo project for Spring Boot + SpringData Redis</description>
    <properties>
        <java.version>11</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <!-- redis 依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
        </dependency>
        <!-- redis 依赖 -->
        <!-- WEB应用 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>参考application.properties文件
server.port=8002
## Redis数据库索引,默认为0
spring.redis.database=0
## Redis数据库地址,默认为localhost
spring.redis.host=127.0.0.1
## Redis数据库端口,默认为6379
spring.redis.port=6379
# Redis服务器连接密码,默认为空
spring.redis.password=
## Redis连接超时时间,单位毫秒
spring.redis.timeout=3000
## Redis链接超时时间
spring.redis.connect-timeout=3000
## Redis连接池中的最小空闲连接数
spring.redis.jedis.pool.min-idle=0
## Redis连接池中的最大空闲连接数
spring.redis.jedis.pool.max-idle=8
    
     注: 启动SpringBoot后自动装配会加载自动配置类RedisAutoConfiguration ,其上使用了注解@EnableConfigurationProperties(RedisProperties.class), 将RedisProperties配置生效
    
   
    
     application.properties的配置信息会注入对象org.springframework.boot.autoconfigure.data.redis。RedisProperties 中,因此其他可用属性(spring.redis.**)可以参考RedisProperties 对象上的批注说明
    
   
3. 创建测试类UserDTO
package com.boot.redis.domain;
import java.io.Serializable;
public class UserDTO implements Serializable {
    private Long id;
    private String name;
    private String code;
    //省略getter和setter
    @Override
    public String toString() {
        return "UserDTO{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", code='" + code + '\'' +
                '}';
    }
}
通过@Configuration注解创建Bean对象RedisTemplate,
package com.boot.redis.conf;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
public class RedisConfig {
    @Bean
    public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<Object, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory);
        JdkSerializationRedisSerializer jdkSerializer = new JdkSerializationRedisSerializer();
        template.setValueSerializer(jdkSerializer);
        // 使用StringRedisSerializer来序列化和反序列化redis的key值
        template.setKeySerializer(new StringRedisSerializer());
        template.setHashKeySerializer(new StringRedisSerializer());
        template.setHashValueSerializer(new StringRedisSerializer());
        template.afterPropertiesSet();
        return template;
    }
}4. 创建测试Controller,并注入RedisTemplate,这个类只是用于测试,实际项目中并不会以此方式处理登录信息
/login 用于模拟登录
- 
@RequestParam表示登录请求中如果没有带参数,默认为zhangsan ,即/login和/login?username=zhangsan相同 
- 
index 每次自增长1,用于模拟不同的ID 
- 
redisTemplate #execute执行的时候先生成KEY 然后将对象系列化后保存到Redis中 
/login 用于模拟获取登录信息
- @RequestParam表示登录请求中如果没有带参数,默认为1,即/get和/get?uuserid=1相同
- redisTemplate #execute执行的时候先获取Redis中的值然后再转换成对象返回
package com.boot.redis.controller;
import com.boot.redis.domain.UserDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class LoginController {
    //顺序生成ID,用于测试
    private static Long index = 1L;
    @Autowired
    private RedisTemplate redisTemplate;
    @GetMapping("/login")
    public String login(@RequestParam(value = "username", defaultValue = "zhangsan") String name) {
        UserDTO user = new UserDTO();
        user.setCode(""+1000+index);
        user.setName(name);
        user.setId(index++);
        redisTemplate.execute(new RedisCallback<Object>() {
            @Override
            public Object doInRedis(RedisConnection connection)
                    throws DataAccessException {
                byte[] key = redisTemplate.getStringSerializer().serialize("user.id." + user.getId());
                JdkSerializationRedisSerializer s = (JdkSerializationRedisSerializer) redisTemplate.getValueSerializer();
                connection.set(key, s.serialize(user));
                System.out.println("add");
                return null;
            }
        });
        return String.format("success", name);
    }
    @GetMapping("/get")
    public String get(@RequestParam(value = "userid", defaultValue = "1") String userId) {
        Object object = redisTemplate.execute(new RedisCallback() {
            public Object doInRedis(RedisConnection connection)
                    throws DataAccessException {
                byte[] key = redisTemplate.getStringSerializer().serialize("user.id." + userId);
                if (connection.exists(key)) {
                    JdkSerializationRedisSerializer s = (JdkSerializationRedisSerializer) redisTemplate.getValueSerializer();
                    return s.deserialize(connection.get(key));
                }
                return null;
            }
        });
        if (object == null) {
            return "null";
        } else {
            return ((UserDTO) object).toString();
        }
    }
}
测试:
    先启动一个Redis Server ,这部分内容可以参考
    
     Redis 安装_学然后知不足!-CSDN博客
    
    ,这里不再重复说明
   
    
     1. 测试请求 :http://127.0.0.1:8002/login?username=zhangsan
    
   
     
   
    
     2. 测试请求:http://127.0.0.1:8002/get?userid=1
    
   
     
   
3. 通过RedisDesktopManager工具查看Redis中的信息
     
   
    3.参考源码
   
    
     https://github.com/PNZBEIJINGL/springboot/tree/master/demo-redis
    
   
    4.常见问题
   
ClassNotFoundException: org.apache.commons.pool.impl.GenericObjectPool$Config
Caused by: java.lang.ClassNotFoundException: org.apache.commons.pool.impl.GenericObjectPool$Config
	at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:247)Spring-Data-Redis版本问题,一般是commons-pool2不匹配引起的,可以查看Maven官网中建议的匹配版本, 例如下图
     
   
 
