SpringBoot learning (seven) - springboot quickly integrate Redis

Redis Cache

@

Brief introduction

redis is a high performance database key-value

Advantage
  • Strong performance for read and write operations of the height (the reading speed is 110,000 times / s, write speed is 81000 times / s).

  • Support more rich data types (such as binary Strings, Lists, Hashes, Sets, Ordered Sets)

  • Certain things ability (either successfully executed or not executed at all).

Disadvantaged
  • Fast access memory database, but also consumes hardware memory resources

Note: redis single-threaded merely said in a client request processing network request with a request on this module, for example, but persistence it will reopen a thread / process to be processed.

Redis introduced Cache

Click on the link to download the window redis version, download well, you usually put into the location of the software, namely the extract from the installation is complete. (Note that the files into a directory, read permission if the current user can write, for example, under the window C: \ Program Files (x86 ), this directory by default only administrators privileges to read and write, redis run when you want to this directory written to the log file in real time, without permissions to read and write, the operation will be unsuccessful)

Here Insert Picture Description

Extract from the catalog is shown below, as is the end of Windows, double-click the exe file to open the client, the server.

Here Insert Picture Description

Because this is springboot integration redis series, so you can double-click to open the service side, do not close the cmd window open.
Here Insert Picture Description

Added in pom.xml

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

Add in the application.properties

# Redis
#Redis服务器地址
spring.redis.host=127.0.0.1
#Redis服务器连接端口
spring.redis.port=6379
# Redis服务器连接密码(默认为空)
spring.redis.password=
#Redis数据库索引(默认为0)
spring.redis.database=0  
#连接池最大连接数(使用负值表示没有限制)
spring.redis.jedis.pool.max-active=50
#连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.jedis.pool.max-wait=3000
#连接池中的最大空闲连接
spring.redis.jedis.pool.max-idle=20
#连接池中的最小空闲连接
spring.redis.jedis.pool.min-idle=5
#连接超时时间(毫秒)
spring.redis.timeout=4000

Code combat

After the new directory code shown below

Here Insert Picture Description

Here to explain the role of the main class, Springboot provides RedisTemplate class to operate Redis, but neither comments explaining the class, named the law is not enough, "too literally." So wrote RedisUtil encapsulated Some commonly used methods, RedisConfig mainly to automatically default to manual injection of the injection sequence and added, Chinese avoid distortion problems.

这里特别说一说 RedisUtil 类,搜索 springboot 和 redis 的文章,这个需要自己封装的类网上大多写的非常混乱,而且前后的封装逻辑不一致, 我估计是某位博主从至少三个人那里复制粘贴糅合起来的,然后大家都跟着这位博主复制粘贴,反而成了热门文章。我猜测大家看它是个工具类,而且六百行左右,大多没有仔细琢磨,能简单测试通过即可,但是稍加思考,发现问题真的不少,很容易误导那些喜欢 “拿来主义” 的 “萌新” 。

虽然我这个系列也是快速上手系列,但我理解的快速上手,就是把让人云里雾里的概念讲直白,然后先暂时跳过那些需要深入的,避免刚入手的畏难情绪,把整个操作流程写的清楚明白,给别人讲一千遍道一万句,不如让他对着现成的程序跑一遍,我一直认为:对着一片空白的屏幕学习程序,只会让人愈加焦虑,最好的办法是一边运行,一边深入。

所以我选取了 redis 五大类型中的String,Hash,Set,List,几乎覆盖每个类型,而 SortedSet 没有选取是因为这是有序的Set,可以自己类比。工具类我统一提供的是取值,添加值,删除值,命名规律绝对可以让你 “望文生义” ,其实还有很多方法,这里我不全写出来,是因为五大数据类型都有一堆方法,你不一定用得上,而且很占篇幅,在这里,授人以鱼不如授人以渔,你仔细看看 RedisUtil 的工具类,就会发现规律,比如操作String,大多是先调用opsForValue()方法,操作Hash,大多先调用opsForHash()方法,把项目源码下载到本地,idea里面点进去,就能看到相关的一堆方法。工具类只是重新调用了,换了个名字,加了些逻辑处理。

别看是热门文章就盲从,我举几个刚才说的问题,

Here Insert Picture Description

Here Insert Picture Description
还有这个的注释说明风格也不统一,给人的感觉看着容易云里雾里的,网上的工具类还用的都是这一个,真的是哭笑不得,大家抄来抄去,都是方案整合商,就不要……

下面开始代码示范

RedisController.java

package com.example.controller;

import com.example.service.IRedisService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping("redis")
public class RedisController {

    @Autowired
    private IRedisService redisService;

    @RequestMapping("/redisString")
    public void redisString() {
        this.redisService.redisString();
    }

    @RequestMapping("/redisHash")
    public void redisHash() {
        this.redisService.redisHash();
    }

    @RequestMapping("/redisSet")
    public void redisSet() {
        this.redisService.redisSet();
    }

    @RequestMapping("/redisList")
    public void redisList() {
        this.redisService.redisList();
    }

    @RequestMapping("/redisSortedSet")
    public void redisSortedSet() {
        //有序的set,故而省略
    }

}

IRedisService.java

package com.example.service;

public interface IRedisService {

    void redisString();

    void redisHash();

    void redisSet();

    void redisList();

    void redisSortedSet();
    
}

RedisServiceIml.java

package com.example.service;

import com.example.util.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.Set;

@Service("redisService")
public class RedisServiceIml implements IRedisService {
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Resource
    private RedisUtil redisUtil;

    public void redisString() {
        //添加值
        redisUtil.stringSet("AAA", "这是一个String类型的值");
        //取值
        Object value = redisUtil.stringGet("AAA");
        System.out.println(value);
    }

    public void redisHash() {
        //添加值
        redisUtil.hashSet("BBB", "test1", "原hash值1");
        redisUtil.hashSet("BBB", "test2", "新hash值1");
        redisUtil.hashSet("BBB", "test1", "原hash值2");
        redisUtil.hashSet("BBB", "test2", "新hash值2");
        //取值
        Object value1 = redisUtil.hashGet("BBB", "test1");
        Object value2 = redisUtil.hashGet("BBB", "test2");
        System.out.println(value1);
        System.out.println(value2);
    }

    public void redisSet() {
        //添值
        redisUtil.setSet("CCC", "这是一组Set集合的第一个");
        redisUtil.setSet("CCC", "这是一组Set集合的第二个");
        redisUtil.setSet("CCC", "这是一组Set集合的第三个");
        //取值
        Set vaule = redisUtil.setGet("CCC");
        System.out.println(vaule);
    }

    public void redisList() {
        //添加值
        redisUtil.listSet("DDD", "这是一组List集合的第一个");
        redisUtil.listSet("DDD", "这是一组List集合的第二个");
        redisUtil.listSet("DDD", "这是一组List集合的第三个");
        //取值
        List list = redisUtil.listGet("DDD", 0, -1);
        System.out.println(list);
    }

    public void redisSortedSet() {
        //有序的set,故而省略
    }

}

RedisConfig.java

package com.example.config;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
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.*;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {

    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {

        RedisTemplate<String, Object> template = new RedisTemplate<>();
        // 配置连接工厂
        template.setConnectionFactory(factory);

        //序列化和反序列化redis中的值
        Jackson2JsonRedisSerializer jackson = new Jackson2JsonRedisSerializer(Object.class);
        //Java对象转换成JSON结构
        ObjectMapper objectMapper = new ObjectMapper();
        // 指定要序列化的域
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        // 指定序列化输入的类型
        objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson.setObjectMapper(objectMapper);

        // 值采用json序列化
        template.setValueSerializer(jackson);
        //使用StringRedisSerializer来序列化和反序列化redis的key值
        template.setKeySerializer(new StringRedisSerializer());

        // 设置hash key和value序列化模式
        template.setHashKeySerializer(new StringRedisSerializer());
        template.setHashValueSerializer(jackson);
        template.afterPropertiesSet();

        return template;
    }

}

RedisUtil.java

package com.example.util;

import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

@Component
public class RedisUtil {
    
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    //===============缓存相关方法===============

    //指定缓存失效时间
    public boolean expire(String key, long time) {
        try {
            if (time > 0) {
                redisTemplate.expire(key, time, TimeUnit.SECONDS);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    //根据key获取过期时间,返回0代表为永久有效
    public long getExpire(String key) {
        return redisTemplate.getExpire(key, TimeUnit.SECONDS);
    }

    //===============数据类型为String的相关方法===============

    //根据key值获取缓存值
    public Object stringGet(String key) {
        return key == null ? null : redisTemplate.opsForValue().get(key);
    }

    //根据key值存入数据类型为String的缓存值
    public boolean stringSet(String key, Object value) {
        try {
            redisTemplate.opsForValue().set(key, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    //根据key值存入数据类型为String的缓存值并设置时间
    public boolean stringSetWithTime(String key, Object value, long time) {
        try {
            if (time > 0) {
                redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
            } else {
                expire(key, time);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    //删除缓存
    public void stringDelete(String... key) {
        if (key != null && key.length > 0) {
            if (key.length == 1) {
                redisTemplate.delete(key[0]);
            } else {
                redisTemplate.delete(CollectionUtils.arrayToList(key));
            }
        }
    }

    //===============数据类型为Hash的相关方法===============

    //根据key和item获取缓存值
    public Object hashGet(String key, String item) {
        return redisTemplate.opsForHash().get(key, item);
    }

    //根据key和item存入数据类型为Hash的缓存值
    public boolean hashSet(String key, String item, Object value) {
        try {
            redisTemplate.opsForHash().put(key, item, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    //根据key和item存入数据类型为Hash的缓存值并设置时间
    public boolean hashSetWithTime(String key, String item, Object value, long time) {
        try {
            redisTemplate.opsForHash().put(key, item, value);
            if (time > 0) {
                expire(key, time);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    //删除缓存
    public void hashDelete(String key, Object... item) {
        redisTemplate.opsForHash().delete(key, item);
    }

    //===============数据类型为SET的相关方法===============

    //根据key值获取缓存值
    public Set<Object> setGet(String key) {
        try {
            return redisTemplate.opsForSet().members(key);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    //根据key值存入数据类型为SET的缓存值
    public long setSet(String key, Object... values) {
        try {
            return redisTemplate.opsForSet().add(key, values);
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }

    //根据key值存入数据类型为SET的缓存值并设置时间
    public long setSetWithTime(String key, long time, Object... values) {
        try {
            Long count = redisTemplate.opsForSet().add(key, values);
            if (time > 0) {
                expire(key, time);
            }
            return count;
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }

    //删除缓存
    public long setDelete(String key, Object... values) {
        try {
            Long count = redisTemplate.opsForSet().remove(key, values);
            return count;
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }

    //===============数据类型为LIST的相关方法===============
    //获取List缓存的内容,从start到end,若从0到-1代表所有值
    public List<Object> listGet(String key, long start, long end) {
        try {
            return redisTemplate.opsForList().range(key, start, end);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    //根据key值存入数据类型为List的缓存值
    public boolean listSet(String key, Object value) {
        try {
            redisTemplate.opsForList().rightPush(key, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    //根据key值存入数据类型为List的缓存值并设置时间
    public boolean listSetWithTime(String key, Object value, long time) {
        try {
            redisTemplate.opsForList().rightPush(key, value);
            if (time > 0) {
                expire(key, time);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    //删除缓存
    public long listDelete(String key, long count, Object value) {
        try {
            Long remove = redisTemplate.opsForList().remove(key, count, value);
            return remove;
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }


}

After starting the project, the browser input http: // localhost: 8080 / redis / redisString, (the front desk will complain, because this request only trigger business logic background, no front page display) operation String type renderings are as follows;

Here Insert Picture Description
After starting the project, the browser input http: // localhost: 8080 / redis / redisHash, Hash operation type renderings are as follows; (note, I had to write code is to insert the four values, print out only two because if the key value and item values, the new values will overwrite the original value, and code comparison chart, you goods, you fine chemicals).
Here Insert Picture Description
after starting the project, the browser input http: // localhost: 8080 / redis / redisSet, Set operation type as shown in FIG effect; (Set are unordered)
Here Insert Picture Description
after starting the project, the browser input http: // localhost: 8080 / redis / redisList, List operation type as shown in FIG effect;

Here Insert Picture Description

Note: If the paper is based on a series of articles to come, since the beginning configured the spring security, so remember the address assigned to the user login. Or the opening of a super administrator account, you can access any directory project, use the administrator account to access these addresses.

This is the source of all the learning series, if there do not understand, want to enrich their own practical operation in which content can be downloaded to a local,

GitHub , the code cloud

Guess you like

Origin www.cnblogs.com/lgx211/p/11978701.html