Youngljx.top is a personal blog about the learning path of Java

SpringBoot integrates the Redis cache

Prerequisite: Know Redis

Redis is an open source (BSD licensed), memory-stored data structure server that can be used as a database, cache, and message queue agent. It supports String, Hash, List, Set, Zset and other data types. Built-in replication, Lua scripting, LRU recall, transactions, and different levels of disk persistence, as well as high availability through Redis Sentinel and automatic partitioning through Redis Cluster.

Learn more about Redis and use Redis in Spring Boot projects

Install and configure Redis for the Linux CentOS server

Install online install, download, decompress, or install directly using the pagoda panel (the path is different from the previous two)

Configure redis parameters:

Daemonize = yes = yes = yes = yes = yes = yes = yes = yes = yes = yes = yes = yes Protected-mode no Disables the protection modeCopy the code

Configure CentOS to disable remote firewall connection to Redis

1: View the firewall status systemctl status Firewalld or service iptables status3: permanently disables the firewall systemctl disable firewalld or chkconfig iptables offCopy the code

Start Redis and navigate to the redis installation directory

Front desk startup: Conf (copy the redis.conf file to the redis installation directory)./redis-server redis.confCopy the code

Login redis

 redis-cli -a  your password
Copy the code

To close Redis, enter shutdown on the console and use exit or direct command

redis-cli -p 6379 -a your password shutdown
Copy the code

Locally use the visualization tool Redis Desktop Manager to remotely connect to Redis by entering the IP address and password

Integration solution 1: Spring Data Redis

Introduce redis dependencies

<! -- Redis dependencies -> <! -- After Spring Boot 2.x, Jedis is no longer used in the underlying layer. Lettuce- > <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <! Commons -pool2</artifactId> Commons -> <dependency> <groupId>org.apache.commons</groupId> <artifactId> </dependency>Copy the code

Parameter configuration The specific parameter configuration reference: org. Springframework. Boot. Autoconfigure. Data. Redis. RedisProperties

Port =6379 #redis connection password Spring. Redis. Password = your password # redis database index (the default is 0) spring. Redis. Database = 0 spring. Redis. Lettuce. The pool. The Max - active = 8 # connection pool biggest jam waiting time (use a negative value indicates no limit) spring. Redis. Lettuce. The pool. The Max - wait = # 1 ms connection pool the largest free connection spring. Redis. Lettuce. The pool. The Max - idle = 8 # connection pool minimum idle connections in the spring. The redis. Lettuce. Pool. Min - idle = 0 # connection timeout time (milliseconds) spring. Redis. Lettuce. The shutdown - timeout = 100 msCopy the code

RedisTemplate
and StringRedisTemplate
and StringRedisTemplate
If the developer does not provide the Bean, these two configurations will take effect and can be injected directly, otherwise they will not take effect.,object>
,object>
,object>

@Configuration(
    proxyBeanMethods = false
)
@ConditionalOnClass({RedisOperations.class})
@EnableConfigurationProperties({RedisProperties.class})
@Import({LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class})
public class RedisAutoConfiguration {
    public RedisAutoConfiguration(a) {}@Bean
    @ConditionalOnMissingBean(
        name = {"redisTemplate"})public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
        RedisTemplate<Object, Object> template = new RedisTemplate();
        template.setConnectionFactory(redisConnectionFactory);
        return template;
    }

    @Bean
    @ConditionalOnMissingBean
    public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
        StringRedisTemplate template = new StringRedisTemplate();
        template.setConnectionFactory(redisConnectionFactory);
        returntemplate; }}Copy the code

StringRedisTemplate is just an implementation of RedisTemplate

. The source code is as follows:
,>

public class StringRedisTemplate extends RedisTemplate<String.String> {
    public StringRedisTemplate(a) {
        this.setKeySerializer(RedisSerializer.string());
        this.setValueSerializer(RedisSerializer.string());
        this.setHashKeySerializer(RedisSerializer.string());
        this.setHashValueSerializer(RedisSerializer.string());
    }

    public StringRedisTemplate(RedisConnectionFactory connectionFactory) {
        this(a);this.setConnectionFactory(connectionFactory);
        this.afterPropertiesSet();
    }

    protected RedisConnection preProcessConnection(RedisConnection connection, boolean existingConnection) {
        return new DefaultStringRedisConnection(connection);
    }
Copy the code

RedisConfig Customizes the serialized RedisTemplate template configuration

Customize serialization notes by following the auto-configuration RedisTemplate class: serializer for RedisTemplate

/ * * *@description: custom serialized RedisTemplate configuration */
@Configuration
@AutoConfigureAfter(RedisAutoConfiguration.class)
public class RedisConfig {

     @Bean
     public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory connectionFactory){
         RedisTemplate<String, Object>  template= new RedisTemplate<>();

         // Set the serialization and deserialization types for key to StringRedisSerializer
        template.setKeySerializer(new StringRedisSerializer());
        template.setHashKeySerializer(new StringRedisSerializer());

         / / set the value of the type of serialization and deserialization Using GenericJackson2JsonRedisSerializer
        template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
        template.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());

        template.setConnectionFactory(connectionFactory);
        returntemplate; }}Copy the code

RedisUtils encapsulates the RedisTempates utility class

Note the common functions used to parse and use RedisTemplate data manipulation

@Component
public class RedisUtils {
    / * * *@DescriptionInject a custom RedisTemplate */
    @Autowired
    private RedisTemplate<String, Object>  redisTemplate ;
    
//==============================common============================
    /** * specifies the cache expiration time **@paramThe key key *@paramTime Time (seconds) *@return* /
    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; }}/** * Obtain expiration time by key **@paramThe key key cannot be NULL *@returnTime (s) returns 0 for permanently valid */
    public long getExpire(String key) {
        return redisTemplate.getExpire(key, TimeUnit.SECONDS);
    }

    /** * Check whether key exists **@paramThe key key *@returnTrue Exists false Does not exist */
    public boolean hasKey(String key) {
        try {
            return redisTemplate.hasKey(key);
        } catch (Exception e) {
            e.printStackTrace();
            return false; }}/** * delete cache **@paramKey can pass one value or more */
    @SuppressWarnings("unchecked")
    public void del(String... key) {
        if(key ! =null && key.length > 0) {
            if (key.length == 1) {
                redisTemplate.delete(key[0]);
            } else{ redisTemplate.delete(CollectionUtils.arrayToList(key)); }}}// ============================String=============================

    /** * Ordinary cache fetch **@paramThe key key *@returnValue * /
    public Object get(String key) {
        return key == null ? null : redisTemplate.opsForValue().get(key);
    }

    /** * Normal cache into **@paramThe key key *@paramThe value value *@returnTrue Successful false failed */
    public boolean set(String key, Object value) {
        try {
            redisTemplate.opsForValue().set(key, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false; }}/** * Normal cache is placed and set time **@paramThe key key *@paramThe value value *@paramTime Time (s) Time must be greater than 0. If time is less than or equal to 0, the value is set indefinitely *@returnTrue Successful false failed */
    public boolean set(String key, Object value, long time) {
        try {
            if (time > 0) {
                redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
            } else {
                set(key, value);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false; }}/** * increment **@paramThe key key *@paramDelta is incremented by a number (greater than 0) *@return* /
    public long incr(String key, long delta) {
        if (delta < 0) {
            throw new RuntimeException("The increasing factor must be greater than zero.");
        }
        return redisTemplate.opsForValue().increment(key, delta);
    }

    /** * decrements **@paramThe key key *@paramDelta is reduced by a number (less than 0) *@return* /
    public long decr(String key, long delta) {
        if (delta < 0) {
            throw new RuntimeException("The decrement factor must be greater than zero.");
        }
        return redisTemplate.opsForValue().increment(key, -delta);
    }
// ================================Map=================================

    /**
     * HashGet
     *
     * @paramThe key key cannot be NULL *@paramItem items cannot be null *@returnValue * /
    public Object hget(String key, String item) {
        return redisTemplate.opsForHash().get(key, item);
    }

    /** * get all keys ** corresponding to the hashKey@paramThe key key *@returnCorresponding multiple key values */
    public Map<Object, Object> hmget(String key) {
        return redisTemplate.opsForHash().entries(key);
    }

    /**
     * HashSet
     *
     * @paramThe key key *@paramMap corresponds to multiple key values *@returnTrue Successful false failed */
    public boolean hmset(String key, Map<String, Object> map) {
        try {
            redisTemplate.opsForHash().putAll(key, map);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false; }}/** * HashSet and set the time **@paramThe key key *@paramMap corresponds to multiple key values *@paramTime Time (seconds) *@returnTrue Successful false failed */
    public boolean hmset(String key, Map<String, Object> map, long time) {
        try {
            redisTemplate.opsForHash().putAll(key, map);
            if (time > 0) {
                expire(key, time);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false; }}/** * puts data into a hash table, or creates ** if none exists@paramThe key key *@paramItem item *@paramThe value value *@returnTrue Successful false failed */
    public boolean hset(String key, String item, Object value) {
        try {
            redisTemplate.opsForHash().put(key, item, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false; }}/** * puts data into a hash table, or creates ** if none exists@paramThe key key *@paramItem item *@paramThe value value *@paramTime Time (s) Note: If the existing hash table has time, the original time * will be replaced@returnTrue Successful false failed */
    public boolean hset(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; }}/** * Delete the value ** from the hash table@paramThe key key cannot be NULL *@paramItem items can be more than null */
    public void hdel(String key, Object... item) {
        redisTemplate.opsForHash().delete(key, item);
    }

    /** * Determines whether the item value ** exists in the hash table@paramThe key key cannot be NULL *@paramItem items cannot be null *@returnTrue Exists false Does not exist */
    public boolean hHasKey(String key, String item) {
        return redisTemplate.opsForHash().hasKey(key, item);
    }

    /** * hash increments that do not exist create one and return the new value **@paramThe key key *@paramItem item *@paramBy is going to be increased by how much (greater than 0) star@return* /
    public double hincr(String key, String item, double by) {
        return redisTemplate.opsForHash().increment(key, item, by);
    }

    /** * hash decrement **@paramThe key key *@paramItem item *@paramI'm going to subtract by (less than 0) star@return* /
    public double hdecr(String key, String item, double by) {
        return redisTemplate.opsForHash().increment(key, item, -by);
    }
// ============================set=============================

    /** * Get all values in Set based on key **@paramThe key key *@return* /
    public Set<Object> sGet(String key) {
        try {
            return redisTemplate.opsForSet().members(key);
        } catch (Exception e) {
            e.printStackTrace();
            return null; }}/** * select * from a set based on value@paramThe key key *@paramThe value value *@returnTrue Exists false Does not exist */
    public boolean sHasKey(String key, Object value) {
        try {
            return redisTemplate.opsForSet().isMember(key, value);
        } catch (Exception e) {
            e.printStackTrace();
            return false; }}/** * Put the data into the set cache **@paramThe key key *@paramValues can be multiple *@returnNumber of successes */
    public long sSet(String key, Object... values) {
        try {
            return redisTemplate.opsForSet().add(key, values);
        } catch (Exception e) {
            e.printStackTrace();
            return 0; }}/** * Put set data into cache **@paramThe key key *@paramTime Time (seconds) *@paramValues can be multiple *@returnNumber of successes */
    public long sSetAndTime(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; }}/** * Get the length of the set cache **@paramThe key key *@return* /
    public long sGetSetSize(String key) {
        try {
            return redisTemplate.opsForSet().size(key);
        } catch (Exception e) {
            e.printStackTrace();
            return 0; }}/** * removes ** of value@paramThe key key *@paramValues can be multiple *@returnNumber of removals */
    public long setRemove(String key, Object... values) {
        try {
            Long count = redisTemplate.opsForSet().remove(key, values);
            return count;
        } catch (Exception e) {
            e.printStackTrace();
            return 0; }}// ===============================list=================================

    /** * retrieve the contents of the list cache **@paramThe key key *@paramStart to *@paramEnd End 0 to -1 represent all values *@return* /
    public List<Object> lGet(String key, long start, long end) {
        try {
            return redisTemplate.opsForList().range(key, start, end);
        } catch (Exception e) {
            e.printStackTrace();
            return null; }}/** * Get the length of the list cache **@paramThe key key *@return* /
    public long lGetListSize(String key) {
        try {
            return redisTemplate.opsForList().size(key);
        } catch (Exception e) {
            e.printStackTrace();
            return 0; }}/** * Get the value ** from the list by index@paramThe key key *@paramIndex index>=0, 0, 1, second element, and so on; When index<0, -1, the end of the table, the next-to-last element of -2, and so on@return* /
    public Object lGetIndex(String key, long index) {
        try {
            return redisTemplate.opsForList().index(key, index);
        } catch (Exception e) {
            e.printStackTrace();
            return null; }}/** * Put the list in the cache **@paramThe key key *@paramThe value value *@return* /
    public boolean lSet(String key, Object value) {
        try {
            redisTemplate.opsForList().rightPush(key, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false; }}/** * Put the list in the cache **@paramThe key key *@paramThe value value *@paramTime Time (seconds) *@return* /
    public boolean lSet(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; }}/** * Put the list in the cache **@paramThe key key *@paramThe value value *@return* /
    public boolean lSet(String key, List<Object> value) {
        try {
            redisTemplate.opsForList().rightPushAll(key, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false; }}/** * Put the list in the cache **@paramThe key key *@paramThe value value *@paramTime Time (seconds) *@return* /
    public boolean lSet(String key, List<Object> value, long time) {
        try {
            redisTemplate.opsForList().rightPushAll(key, value);
            if (time > 0) {
                expire(key, time);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false; }}/** * Modify a list of data ** based on the index@paramThe key key *@paramThe index index *@paramThe value value *@return* /
    public boolean lUpdateIndex(String key, long index, Object value) {
        try {
            redisTemplate.opsForList().set(key, index, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false; }}/** * remove N values to value **@paramThe key key *@paramCount removes how many *@paramThe value value *@returnNumber of removals */
    public long lRemove(String key, long count, Object value) {
        try {
            Long remove = redisTemplate.opsForList().remove(key, count, value);
            return remove;
        } catch (Exception e) {
            e.printStackTrace();
            return 0; }}}Copy the code

Run the unit tests and view the database data in the Redis client, Redis Desktop Manager.

The original reference links blog.csdn.net/zhulier1124…

Integration solution 2: Spring Cache

SpringBoot uses Spring cache annotations

Key notes:

@CacheConfig

This annotation is used on a class to describe the cache names used by all methods in that class.

@Cacheable

This annotation is usually added to a query method to indicate that the return value of a method is cached. By default, the cached key is the method parameter and the cached value is the method return value.

@CachePut

This annotation is usually applied to the update method. When the data in the database is updated, the data in the cache is also updated. Using this annotation, the return value of the method is automatically updated to the existing key.

@CacheEvict

This annotation is usually added to the delete method. When the data in the database is deleted, the associated cached data is also deleted.