SpringBoot learning spike 1. SpringBoot integrates Redis (implemented using Jedis)

There is already a well-implemented jar package in Springboot that can easily integrate Redis, or you can encapsulate Jedis to implement Redis by yourself. Here we use Jedis to encapsulate, so that our program is more flexible. First, we need to install Redis
: redis After the download and
installation is complete, enter redis-cli in the console. If the following interface appears, it means the installation is successful.
insert image description here
After the redis installation is successful, open the idea. We create a new Springboot project, select Create New Project
and select the new project type as Spring Initializr, which is very convenient. Create a new Springboot project.
insert image description here
I use Maven as the package management here, so the generated project directory looks like this.
insert image description here
After the project is created, we need to add jedis dependencies. Open
pom.xml and add<dependencies></dependencies>

	<dependency>
        <groupId>redis.clients</groupId>
        <artifactId>jedis</artifactId>
        <version>3.2.0</version>
    </dependency>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>fastjson</artifactId>
        <version>1.2.62</version>
    </dependency> 

Among them, jedis is the java client of redis, and FastJson is a tool that can convert JavaBean into JSON string, because Redis storage is stored in the form of string by default, so when we store JavaBean, we need to JavaBean is serialized into a JSON string, and when we take it out, we also need to convert the string into a JavaBean.
Then we need to define the configuration parameters of Redis in the SpringBoot configuration file. In the SpringBoot project generated by Idea, we have added the Application.properties file as the configuration file by default. Here we replace it with a more convenient yml file
insert image description here
in In the newly created application.yml file, write our redis configuration parameters

redis:
  host: 127.0.0.1   # redis服务器的地址
  port: 6379   #redis服务器的端口  默认为6379
  timeout: 3  #客户端超时时长
  password:   #redis客户端密码
  poolMaxTotal: 10   #redis连接池最大连接
  poolMaxIdle: 10  #连接池最大空闲连接数
  poolMaxWait: 5  # 连接最大等待时间(毫秒)

We create a new package named redis to save our encapsulated Redis code.
First, we need a configuration class to read in the configuration items we defined in the configuration file.
Use @Componetto indicate that this class is a SpringBoot component class, and
use @ConfigurationProperties(prefix = "redis")to identify us The prefix of the read configuration item is redis
RedisConfig.java

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Component
@ConfigurationProperties(prefix = "redis")
public class RedisConfig {
    private String host;
    private int port;
    private int timeout;
    private String password;
    private int poolMaxTotal;
    private int poolMaxIdle;
    private int poolMaxWait;

    public String getHost() {
        return host;
    }

    public void setHost(String host) {
        this.host = host;
    }

    public int getPort() {
        return port;
    }

    public void setPort(int port) {
        this.port = port;
    }

    public int getTimeout() {
        return timeout;
    }

    public void setTimeout(int timeout) {
        this.timeout = timeout;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public int getPoolMaxTotal() {
        return poolMaxTotal;
    }

    public void setPoolMaxTotal(int poolMaxTotal) {
        this.poolMaxTotal = poolMaxTotal;
    }

    public int getPoolMaxIdle() {
        return poolMaxIdle;
    }

    public void setPoolMaxIdle(int poolMaxIdle) {
        this.poolMaxIdle = poolMaxIdle;
    }

    public int getPoolMaxWait() {
        return poolMaxWait;
    }

    public void setPoolMaxWait(int poolMaxWait) {
        this.poolMaxWait = poolMaxWait;
    }
}

Next, we create a new RedisService to encapsulate jedis.
We need two basic methods to operate redis. One is to store data in redis,
<T> boolean set(String key,Class<T> clazz)
and the other is <T> T get(String key ,Class <T> clazz)
to Converting to String type for storage, so we define a BeanToStringmethod, the code is as follows:

private <T> String beanToString(T value) {
        if (null == value) {
            return null;
        }
        Class<?> clazz = value.getClass();
        if (clazz == int.class || clazz == Integer.class) return "" + value;
        else if (clazz == long.class || clazz == Long.class) return "" + value;
        else if (clazz == String.class) return String.valueOf(value);
        else return JSON.toJSONString(value);
    }

Similarly, we also need to convert String to Bean when reading, so we need to define a StringToBeanmethod:

private <T> T stringToBean(String str, Class<T> clazz) {
       if (null == str || str.length() <= 0 || null == clazz) {
           return null;
       }
       if (clazz == int.class || clazz == Integer.class) return (T) Integer.valueOf(str);
       else if (clazz == long.class || clazz == Long.class) return (T) Long.valueOf(str);
       else if (clazz == String.class) return (T) str;
       else return (T) JSON.toJavaObject(JSON.parseObject(str), clazz);
   }

Then we can write and read. We use the jedis client get setmethod to do it. How to get the jedis object? We can directly instantiate a Jedis object, but because we want to use the connection pool, so We need a JedisPool to instantiate our Jedis, we create a new fileRedisFactory

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

@Service
public class RedisFactory {

    @Autowired
    private RedisConfig redisConfig;

    @Bean
    public JedisPool jedisPoolFactory(){
        JedisPoolConfig poolConfig = new JedisPoolConfig();
        poolConfig.setMaxTotal(redisConfig.getPoolMaxTotal());
        poolConfig.setMaxIdle(redisConfig.getPoolMaxIdle());
        poolConfig.setMaxWaitMillis(redisConfig.getPoolMaxWait() * 1000);
        return new JedisPool(poolConfig,redisConfig.getHost(),redisConfig.getPort(),redisConfig.getTimeout());
    }


}

Then inject our RedisFactory in our RedisService

	@Autowired 
	private JedisPool jedisPool; 

Next, we JedisPool.getResource()can get our Jedisobjects through
Next, we will write our set and get methods

/**
     * redis 中设置值
     * @param prefix
     * @param key
     * @param value
     * @param <T>
     * @return
     */
    public <T> boolean set(String key, T value) {
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            String str = beanToString(value);
            if (null == str || str.length() <= 0) return false;
            jedis.set(str , str);
            return true;
        } finally {
            returnToPool(jedis);
        }
    }


/**
     * redis 中获取值
     * @param prefix
     * @param key
     * @param clazz
     * @param <T>
     * @return
     */
    public <T> T get(String key, Class<T> clazz) {
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            String str = jedis.get(key);
            return stringToBean(str, clazz);
        } finally {
            returnToPool(jedis);
        }
    }
	
	/**
		连接使用完成之后放回连接池
	**/
	private void returnToPool(Jedis jedis) {
        if (null != jedis) jedis.close();
    }

After the most basic get and set methods, let's define some commonly used methods

/**
     * 判断redis 中key是否存在
     * @param prefix
     * @param key
     * @param <T>
     * @return
     */
    public <T> boolean exists(String key,String key) {
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            return jedis.exists(key);
        } finally {
            returnToPool(jedis);
        }
    }
    
/**
     * redis 数值增加
     * @param prefix
     * @param key
     * @param <T>
     * @return
     */
    public <T> Long incr(String key,String key) {
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            return jedis.incr(key);
        } finally {
            returnToPool(jedis);
        }
    }

 /**
     * redis 数值减少
     * @param prefix
     * @param key
     * @param <T>
     * @return
     */
    public <T> Long decr(String key,String key) {
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            return jedis.decr(key);
        } finally {
            returnToPool(jedis);
        }
    }

Well, our Redis client is basically packaged, but there is still a problem, that is, our Key is passed in as a string. Since the storage of Redis is in the form of Key and Value, we store it in The Value value of is likely to be overwritten by the same value as the Key, so in order to solve this problem, we need to add a prefix to the Key we pass in.
Let's define an interface to implement the prefix, define two methods in the interface, one expireSecondsmeans we store the expiration time getPrefixto get our prefix

public interface KeyPrefix {
    public int expireSeconds();
    public String getPrefix();
}

Then set a Base class to implement this interface, we use "class name: prefix" as the prefix of our key

public abstract class BasePrefix implements KeyPrefix {

    private int expireSeconds;
    private String prefix;

    public BasePrefix(String prefix){
        this(0,prefix);
    }

    public BasePrefix(int expireSeconds,String prefix){
        this.expireSeconds = expireSeconds;
        this.prefix = prefix;
    }

    @Override
    public int expireSeconds() {
        return 0;
    }

    @Override
    public String getPrefix() {
        String className = getClass().getSimpleName();
        return className + ":" + prefix;
    }
}

Next, we write a UserKey to inherit our BasePrefix. We assume that there are two ways to store User from Redis, one is to get by id getByIdand by namegetByName

public class Userkey extends BasePrefix {
    private  Userkey(String prefix) {
        super(prefix);
    }
    public static Userkey getById = new Userkey("id");
    public static Userkey getByName = new Userkey("name");

}

Next, we need to modify our RedisService so that each method of operating Redis must carry a Prefix. The complete code is as follows:

package com.newcode.seckill_redis.redis;

import com.alibaba.fastjson.JSON;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

@Service
public class RedisService {

    @Autowired
    private JedisPool jedisPool;

    /**
     * redis 中获取值
     * @param prefix
     * @param key
     * @param clazz
     * @param <T>
     * @return
     */
    public <T> T get(KeyPrefix prefix,String key, Class<T> clazz) {
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            String realKey = prefix.getPrefix() + key;
            String str = jedis.get(realKey);
            return stringToBean(str, clazz);
        } finally {
            returnToPool(jedis);
        }
    }

    /**
     * redis 中设置值
     * @param prefix
     * @param key
     * @param value
     * @param <T>
     * @return
     */
    public <T> boolean set(KeyPrefix prefix,String key, T value) {
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            String str = beanToString(value);
            if (null == str || str.length() <= 0) return false;
            String realKey = prefix.getPrefix() + key;
            int seconds = prefix.expireSeconds();
            if(seconds > 0 )
                jedis.setex(realKey,seconds,str);
            else
                jedis.set(realKey, str);
            return true;
        } finally {
            returnToPool(jedis);
        }
    }

    /**
     * 判断redis 中key是否存在
     * @param prefix
     * @param key
     * @param <T>
     * @return
     */
    public <T> boolean exists(KeyPrefix prefix,String key) {
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            String realKey = prefix.getPrefix() + key;
            return jedis.exists(realKey);
        } finally {
            returnToPool(jedis);
        }
    }

    /**
     * redis 数值增加
     * @param prefix
     * @param key
     * @param <T>
     * @return
     */
    public <T> Long incr(KeyPrefix prefix,String key) {
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            String realKey = prefix.getPrefix() + key;
            return jedis.incr(realKey);
        } finally {
            returnToPool(jedis);
        }
    }

    /**
     * redis 数值减少
     * @param prefix
     * @param key
     * @param <T>
     * @return
     */
    public <T> Long decr(KeyPrefix prefix,String key) {
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            String realKey = prefix.getPrefix() + key;
            return jedis.decr(realKey);
        } finally {
            returnToPool(jedis);
        }
    }

    private <T> String beanToString(T value) {
        if (null == value) {
            return null;
        }
        Class<?> clazz = value.getClass();
        if (clazz == int.class || clazz == Integer.class) return "" + value;
        else if (clazz == long.class || clazz == Long.class) return "" + value;
        else if (clazz == String.class) return String.valueOf(value);
        else return JSON.toJSONString(value);
    }


    private <T> T stringToBean(String str, Class<T> clazz) {
        if (null == str || str.length() <= 0 || null == clazz) {
            return null;
        }
        if (clazz == int.class || clazz == Integer.class) return (T) Integer.valueOf(str);
        else if (clazz == long.class || clazz == Long.class) return (T) Long.valueOf(str);
        else if (clazz == String.class) return (T) str;
        else return (T) JSON.toJavaObject(JSON.parseObject(str), clazz);
    }

    private void returnToPool(Jedis jedis) {
        if (null != jedis) jedis.close();
    }


}

Next we can happily use our RedisServie:

 Boolean f = redisService.set(Userkey.getById,"key","value");
 String str = redisService.get(Userkey.getById,"key",String.class);

Complete code example

Guess you like

Origin blog.csdn.net/JiayaoXu/article/details/104416384