springboot整合redis

1.redis的数据类型,一共有5种.后面结合Jedis和redistemplate,以及单元测试junit一起验证
 1)字符串
 2)hash
 3)列表
 4)set(无序集合)
 5)zset(有序集合)
2.Jedis的使用
 a)引入依赖

<!--加入springboot的starter的起步依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
            <version>2.1.4.RELEASE</version>
        </dependency>
<!--springboot整合redis-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
            <version>2.1.4.RELEASE</version>
        </dependency>
<!--jedis依赖-->
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>2.9.1</version>
        </dependency>
<!--lombok依赖-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.20</version>
        </dependency>
<!--配置springboot注解执行器用于yml文件提示-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <version>2.1.4.RELEASE</version>
        </dependency>
<!--springboot整合junit-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <version>2.1.4.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-test</artifactId>
            <version>2.1.4.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
            <version>2.6.2</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

.b)配置yml和启动文件.这里需要注意一下,在使用redis数据库时,是不需要密码验证的.但是在后面配置RedisPoolFactory时,需要配置登录密码.因此,在yml这里需要设置密码,否则在test时会报错.

redis:
    host: 127.0.0.1
    password: 123456
    port: 6379
    timeout: 6
    poolMaxTotal: 30
    poolMaxIdle: 30
    poolMaxWait: 30
@SpringBootApplication
public class MySpringBootApplication {

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

}

. 1)同时设置redis的登录密码

redis设置密码
验证登录: auth 123456
设置密码: config set requirepass 123456

.c)编写配置文件注入参数

@Data
@Component
@ConfigurationProperties(prefix = "redis")
public class RedisConfig1 {
    private String host;
    private int port;
    private int timeout; //秒
    private String password;
    private int poolMaxTotal; //资源池最大连接数
    private int poolMaxIdle; //资源池允许最大空闲连接数
    private int poolMaxWait; //超时时间 s
}

.d)配置RedisPoolFactory

@Service
public class RedisPoolFactory {

    @Autowired
    private RedisConfig1 redisConfig1;

    @Bean
    public JedisPool JedisPoolFactory(){
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        jedisPoolConfig.setMaxTotal(redisConfig1.getPoolMaxTotal());
        jedisPoolConfig.setMaxIdle(redisConfig1.getPoolMaxIdle());
        jedisPoolConfig.setMaxWaitMillis(redisConfig1.getPoolMaxWait() * 1000);
        JedisPool jedisPool = new JedisPool(jedisPoolConfig, redisConfig1.getHost(), redisConfig1.getPort(),
                redisConfig1.getTimeout(), redisConfig1.getPassword());
        return jedisPool;
    }

}

.e)编写测试用例
.  1)配置junit测试,注入RedisPoolFactory,RedisTemplate

@RunWith(SpringRunner.class)
@SpringBootTest(classes = MySpringBootApplication.class)
public class TestJedis {

    @Autowired
    private RedisPoolFactory redisPoolFactory;

    @Autowired
    private RedisTemplate redisTemplate;
}

. 2)测试字符串

    @Test
    public void test1(){
        Jedis jedis = redisPoolFactory.JedisPoolFactory().getResource();
        //设置字符类型数据
        System.out.println("设置字符串类型数据");
        jedis.set("age","11");
        jedis.set("work","doctor");
        System.out.println(jedis.get("age"));
        System.out.println(jedis.get("work"));
        jedis.del("age","doctor");
        jedis.close();
    }

. 3)测试hash

     @Test
     public void test1(){
        Jedis jedis = redisPoolFactory.JedisPoolFactory().getResource();
        //设置hash类型数据
        System.out.println("设置hash类型数据");
        jedis.hset("people1","age","11");
        jedis.hset("people1","work","teacher");
        jedis.hset("people1","name","李四");
        System.out.println(jedis.hget("people1", "age"));
        System.out.println(jedis.hget("people1","work"));
        System.out.println(jedis.hget("people1","name"));
        jedis.del("people1");
        jedis.close();
    }  

. 4)测试列表

    @Test
    public void test1(){
        Jedis jedis = redisPoolFactory.JedisPoolFactory().getResource();
        //设置列表类型数据
        System.out.println("设置列表类型数据");
        jedis.lpush("person","name","age","work");
        //左面弹栈
        List<String> person2 = jedis.lrange("person", 1, 2);
        for (String s : person2) {
            System.out.println("获取列表给定范围元素: "+s);
        }
        System.out.println("左面弹栈");
        System.out.println(jedis.lpop("person"));
        System.out.println(jedis.lpop("person"));
        System.out.println(jedis.lpop("person"));
        //获取列表长度
        System.out.println(jedis.llen("person"));
        //右面弹栈
        System.out.println("右面弹栈");
        System.out.println(jedis.rpop("person"));
        System.out.println(jedis.rpop("person"));
        System.out.println(jedis.rpop("person"));
        jedis.close();
    }

. 5)测试set

    @Test
    public void test1(){
        Jedis jedis = redisPoolFactory.JedisPoolFactory().getResource();
         //设置set类型数据 只可以添加元素
        jedis.sadd("people2", "22", "33", "44","person");
        System.out.println(jedis.smembers("people2"));
        jedis.srem("people2","person");
        System.out.println(jedis.smembers("people2"));
        jedis.close();
    }

. 6)测试zset

@Test
    public void test1(){
        Jedis jedis = redisPoolFactory.JedisPoolFactory().getResource();
        //设置zset有序集合,排序set 从小到大
        jedis.zadd("score",92.00,"小明");
        jedis.zadd("score",69.00,"小兰");
        jedis.zadd("score",72.00,"小红");
        System.out.println(jedis.zrange("score",0,2));
        jedis.close();
    }

. 7)简单demo,排序学生成绩

@Test
    public void test2(){
        Jedis jedis = null;
        try {
            JedisPool jedisPool = redisPoolFactory.JedisPoolFactory();
            jedis = jedisPool.getResource();
            //造数据 学生成绩
            jedis.zadd("score",78,"小明");
            jedis.zadd("score",90,"小红");
            jedis.zadd("score",80,"小蓝");
            jedis.zadd("score",33,"小东");
            jedis.zadd("score",69,"小兰");
            //打印学生排序后的成绩
            Long scoreLength = jedis.zcard("score");
            Set<String> zrange = jedis.zrange("score", 0, scoreLength);
            for (String s : zrange) {
                System.out.println(s);
            }
        }finally {
            if(jedis != null){
                jedis.close();
            }
        }
    }

2.RedisTemplate的使用
 a)编写配置类,这里没有使用yml文件,采用的序列化机制 Jackson2JsonRedisSerializer

@Configuration
public class RedisConfig extends JCacheConfigurerSupport {

    @Bean
    public JedisPoolConfig jedisPoolConfig() {
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        //控制一个pool可分配多少个jedis实例
        jedisPoolConfig.setMaxTotal(500);
        //最大空闲数
        jedisPoolConfig.setMaxIdle(200);
        //每次释放连接的最大数目,默认是3
        jedisPoolConfig.setNumTestsPerEvictionRun(1024);
        //逐出扫描的时间间隔(毫秒) 如果为负数,则不运行逐出线程, 默认-1
        jedisPoolConfig.setTimeBetweenEvictionRunsMillis(30000);
        //连接的最小空闲时间 默认1800000毫秒(30分钟)
        jedisPoolConfig.setMinEvictableIdleTimeMillis(-1);
        jedisPoolConfig.setSoftMinEvictableIdleTimeMillis(10000);
        //最大建立连接等待时间。如果超过此时间将接到异常。设为-1表示无限制。
        jedisPoolConfig.setMaxWaitMillis(1500);
        jedisPoolConfig.setTestOnBorrow(true);
        jedisPoolConfig.setTestWhileIdle(true);
        jedisPoolConfig.setTestOnReturn(false);
        jedisPoolConfig.setJmxEnabled(true);
        jedisPoolConfig.setBlockWhenExhausted(false);
        return jedisPoolConfig;
    }

    @Bean
    public JedisConnectionFactory connectionFactory(JedisPoolConfig jedisPoolConfig) {
        RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration();
        redisStandaloneConfiguration.setHostName("127.0.0.1");
        redisStandaloneConfiguration.setDatabase(0);
        redisStandaloneConfiguration.setPassword("123456");
        redisStandaloneConfiguration.setPort(6379);
        //获得默认的连接池构造器
        JedisClientConfiguration.JedisPoolingClientConfigurationBuilder jpcb =
                (JedisClientConfiguration.JedisPoolingClientConfigurationBuilder)JedisClientConfiguration.builder();
        //指定jedisPoolConifig来修改默认的连接池构造器(真麻烦,滥用设计模式!)
        jpcb.poolConfig(jedisPoolConfig);
        //通过构造器来构造jedis客户端配置
        JedisClientConfiguration jedisClientConfiguration = jpcb.build();
        //单机配置 + 客户端配置 = jedis连接工厂
        return new JedisConnectionFactory(redisStandaloneConfiguration, jedisClientConfiguration);
    }

    @Bean
    public RedisTemplate<Object, Object> redisTemplate(JedisConnectionFactory connectionFactory) {
        RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(connectionFactory);
        //初始化参数和初始化工作
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }

    /**
     * description:  这里的入参使用了转配方式,由spring注入
     *
     * @params No such property: code for class: Script1
     * @return
     */
    @Bean
    public RedisTemplate<String,Object> redisTemplate1(RedisConnectionFactory redisConnectionFactory){
        //采用jackson2JsonRedisSerializer序列化机制
        Jackson2JsonRedisSerializer<Object> objectJackson2JsonRedisSerializer =
                new Jackson2JsonRedisSerializer<>(Object.class);
        ObjectMapper objectMapper = new ObjectMapper();
        //配置采用直接处理字段的方式序列化和反序列化
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        //对象映射器启用默认类型
        objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance,ObjectMapper.DefaultTyping.NON_FINAL,
                JsonTypeInfo.As.PROPERTY);
        objectJackson2JsonRedisSerializer.setObjectMapper(objectMapper);
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        //配置template参数
        template.setConnectionFactory(redisConnectionFactory);
        template.setKeySerializer(objectJackson2JsonRedisSerializer);
        template.setValueSerializer(objectJackson2JsonRedisSerializer);
        template.setHashKeySerializer(objectJackson2JsonRedisSerializer);
        template.setHashValueSerializer(objectJackson2JsonRedisSerializer);
        template.afterPropertiesSet();
        return template;
    }
}

. 1)说明:缺少pom

        <!--lombok依赖-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.20</version>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter</artifactId>
            <version>RELEASE</version>
            <scope>compile</scope>
        </dependency>
        <!--引入jackson的依赖-->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.10.0</version>
        </dependency>
        <dependency>

.b)编写测试用例

@RunWith(SpringRunner.class)
@SpringBootTest(classes = MySpringBootApplication.class)
@ContextConfiguration(classes = {RedisConfig.class})
public class TestRedisTemplate {

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * description: 学习redistemplate
     *
     * @params No such property: code for class: Script1
     * @return
     */
    @Test
    public void test1(){
        //字符串数据类型
        redisTemplate.opsForValue().set("sport","football");
        System.out.println(redisTemplate.opsForValue().get("sport"));
        //hash数据类型
        redisTemplate.opsForHash().put("people","name","小明");
        redisTemplate.opsForHash().put("people","age",25);
        redisTemplate.opsForHash().put("people","salary",null);
        System.out.println(redisTemplate.opsForHash().get("people","name"));
        System.out.println(redisTemplate.opsForHash().get("people","age"));
        System.out.println(redisTemplate.opsForHash().get("people","salary"));
        //列表
        //左边堆栈
        redisTemplate.opsForList().leftPushAll("人生能有几时秋","大江东去浪淘尽",666,"醉酒当歌,人生几何");
        System.out.println(redisTemplate.opsForList().size("人生能有几时秋"));
        //左边弹栈
        System.out.println(redisTemplate.opsForList().leftPop("人生能有几时秋"));
        System.out.println(redisTemplate.opsForList().leftPop("人生能有几时秋"));
        System.out.println(redisTemplate.opsForList().leftPop("人生能有几时秋"));
        System.out.println(redisTemplate.opsForList().leftPop("人生能有几时秋"));
        System.out.println(redisTemplate.opsForList().leftPop("人生能有几时秋"));
        //set数据类型
        redisTemplate.opsForSet().add("person","小兰","小明","承瑞","兆雪");
        redisTemplate.opsForSet().difference("person","星辰大海");
        redisTemplate.opsForSet().difference("person","万古长灯");
        redisTemplate.opsForSet().difference("person",666);
        Set person = redisTemplate.opsForSet().members("person");
        for (Object o : person) {
            System.out.println(o);
        }
        //zset数据类型 这里的数据是double
        redisTemplate.opsForZSet().add("student","小张",89);
        redisTemplate.opsForZSet().add("student","小兰",99);
        redisTemplate.opsForZSet().add("student","小红",79);
        redisTemplate.opsForZSet().add("student","小明",69);
        Long num = redisTemplate.opsForZSet().count("student", 90, 100);
        System.out.println(num);
        Long numTotal = redisTemplate.opsForZSet().size("student");
        Set studentRank = redisTemplate.opsForZSet().range("student", 0, numTotal - 1);
        for (Object o : studentRank) {
            redisTemplate.opsForList().leftPushAll("studentList",o);
        }
        long students = redisTemplate.opsForList().size("studentList");
        for (long i = 0; i < students; i++) {
            System.out.println(String.format("第%s名: "+redisTemplate.opsForList().leftPop("studentList"),
                    i+1));
        }
    }

}

4.使用Jedis和RedisTemplate
 a)RedisTemplate的配置比Jedis的配置类似,但是RedisTemplate使用更方便,它可以自动归还redis连接,同时封装的方法也要比Jedis多

你可能感兴趣的:(springboot,spring,boot,redis,java)