This is the second day of my participation in the More text Challenge. For more details, see more text Challenge

Springboot integrates Redis + Cache


Introduction of redis

Redis (Remote Dictionary Server) is a high-performance key-value database.

Redis and other key-value cache products have the following three features:

Redis supports data persistence, which keeps data in memory on disk and can be reloaded and used upon restart.

Redis supports not only simple key-value data, but also string, hash, list, set, and sorted set data.

Redis supports data backup in master-slave mode.

Springboot integrate redis

1. Rely on

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

Others rely on FastJSON

<dependency>
     <groupId>com.alibaba</groupId>
     <artifactId>fastjson</artifactId>
     <version>1.260.</version>
</dependency>
Copy the code

2. Application. The properties configuration

#Redis #Redis database index (default0) spring. Redis. Database =0# Redis server address spring.redis.host=192.1684.100.# Redis server connection port spring.redis.port=6379# # Redis password spring. Redis. Password = connection pool maximum number of connections (use a negative value indicates no limit) spring. Redis. Jedis. Pool. The Max - active =8# connection pool biggest jam waiting time (use a negative value indicates no limit) spring. Redis. Jedis. Pool. The Max - wait = -1# connection pool in the largest free connection spring. Redis. Jedis. Pool. The Max - idle =8# connection pool minimum idle connections in the spring. The redis. Jedis. Pool. Min - idle =0Spring.redis.timeout =5000

Copy the code

3. The test

@RestController
public class RedisTestCtrl {
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @PostMapping("/user")
    public Object addUser(@RequestBody User user) {
        stringRedisTemplate.opsForValue().set("user", JSON.toJSONString(user));
        return "success";
    }

    @GetMapping("/user")
    public User getUser(a) {
        return JSON.parseObject(stringRedisTemplate.opsForValue().get("user"), User.class);
    }

    @PostMapping("/users")
    public Object addUsers(@RequestBody List<User> users) {
        stringRedisTemplate.opsForList().rightPushAll("users", users.stream().map(JSON::toJSONString).collect(Collectors.toList()));
        return "success";
    }

    @GetMapping("/users")
    public Object getUsers(a) {
        List<User> users = new ArrayList<>();
        while (true) {
            User user = JSON.parseObject(stringRedisTemplate.opsForList().leftPop("users"), User.class);
            if (Objects.isNull(user)) {
                break;
            }
            users.add(user);
        }
        returnusers; }}Copy the code

The above data has been stored in Redis and can be viewed using the Redis visualization tool

Test using the mysql database

1. Add mybatis,mysql dependency, and configure connection

pom

<! --mybatis and mysql--> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.1. 0</version>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
</dependency>
Copy the code

configuration

#mysql
spring.datasource.url=jdbc:mysql:/ / 192.168.4.100:3306 / test
spring.datasource.username=root
spring.datasource.password=123456
Copy the code

2. Build the domain and DAO

Objects need to be serialized

@Data
public class User implements Serializable {
    private String name;
    private int age;
}
Copy the code
@Mapper
public interface UserDao {
    @Select("select * from RedisUser")
    List<User> userList(a);
}

Copy the code

3. Test redis

Check whether there is a cache of the key in the cache. If there is no cache of the key, obtain data from the database and write it to the cache

 @GetMapping("/queryUsers")
    public List<User> queryUsers(a) {
    	// Customize a key as required
        String key = "data";
        ValueOperations<String, List<User>> operations = redisTemplate.opsForValue();
        boolean hasKey = redisTemplate.hasKey(key);
        if (hasKey) {
            List<User> users = operations.get(key);
            System.out.println("========== Get data from cache =========");
            return users;
        } else {
            List<User> users = userDao.userList();
            System.out.println("========== Get data from a data sheet =========");
            // Write to cache and set expiration time
            operations.set(key, users, 5, TimeUnit.SECONDS);
            returnusers; }}Copy the code

The set() method sets the cache expiration timeAt this point, the redis test has been completed

I used the aboveStringRedisTemplateWhen using the database test, I usedRedisTemplateRelevance and distinction?

In the figure above, the User key is using the StringRedisTemplate and the data key is using the RedisTemplate as you can see from the RedisDesktop visualization tool, the data that you maintain with the StringRedisTemplate, the keys and values are strings, Easy maintenance; The data maintained with the RedisTemplate, with its keys and values converted to byte arrays, is unreadable. Suggestion: Use StringRedistemplate for string data, use RedisTemplate for object data, and use StringRedistemplate for object data. If you use StringRedistemplate, you need to convert it to object ==, such as fastJSON to user object.

RedisTemplate and StringRedisTemplate

  1. The relationship between the two is that StringRedisTemplate inherits from RedisTemplate.

  2. The data are not in common; In other words, StringRedisTemplate can only manage the data in StringRedisTemplate, and RedisTemplate can only manage the data in RedisTemplate.

  3. There are two default serialization policies adopted by SDR, one is String serialization policy, the other is JDK serialization policy.

By default, the StringRedisTemplate uses the String serialization policy for storing keys and values.

By default, the RedisTemplate uses the JDK’s serialization policy, which serializes the stored keys and values.

Redistemplate main methods:

The above test only uses redisteplate’s opsForValue() and hasKey() methods;The redistemplate method has many methods, and this is just part of it,Redis five types of data, = = String, a list, hash, set, zset = =, is corresponding to the corresponding method of ops

The following is an example of opsForLIst of the list type

@RequestMapping(value = "/redis/list")
    public void listOperation(a) {
        List<String> list1 = new ArrayList<String>();
        list1.add("a1");
        list1.add("a2");
        list1.add("a3");

        List<String> list2 = new ArrayList<String>();
        list2.add("b1");
        list2.add("b2");
        list2.add("b3");
        // Leftpush is added to the left of the list, i.e. the head of the list, and right is added to the left of the list, i.e. the end of the list.
        / / insert
        redisTemplate.opsForList().leftPush("listkey1",list1);
        redisTemplate.opsForList().rightPush("listkey2", list2);
        
        // The Pop method removes the cache
        List<String> resultList1 = (List<String>) redisTemplate.opsForList().leftPop("listkey1");
        List<String> resultList2 = (List<String>) redisTemplate.opsForList().rightPop("listkey2");
        System.out.println("resultList1:" + resultList1);
        System.out.println("resultList2:" + resultList2);
    }
Copy the code

Other methods

// Set the expiration time
redistemplate.expire(key,seconds,TimeUnit.SECONDS)
// If you want to see only one element. You can use range, it takes three arguments, the first argument is key, and then the search scope,
(key,0,-1);
redisTemplate.opsForList().range("listkey1".0, -1)
Copy the code

The other types of methods are omitted.

springboot cache + redis

As we have already integrated SpringBoot + Redis, we can simplify this further by using cache. By default, SpringBoot integrates cache. You can use annotations.

SpringCache contains two top-level interfaces, Cache and CacheManager. The spring-boot-starter data-Redis has automatically configured the Cache interface, which is easy to use

test

 @GetMapping("/getUser")
    @Cacheable(cacheNames = "aa",key = "#p0")
    public User addUser(String id) {
        log.info("Entry data");
        User user = new User("xiaomi".19);
        return user;
    }
Copy the code

The Redis database was saved successfully, but as a byte array.

The configuration is converted to JSON

@configuration public class MyRedisConfig {public MyRedisConfig() {} /** * */ @bean public distemplate <Object, User> userRedisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException { RedisTemplate<Object, User> template = new RedisTemplate(); template.setConnectionFactory(redisConnectionFactory); Jackson2JsonRedisSerializer<User> serializer = new Jackson2JsonRedisSerializer<User>(User.class); template.setDefaultSerializer(serializer); return template; } / * * * reference org. Springframework. Boot. Autoconfigure. Cache. RedisCacheConfiguration; */ @bean public RedisCacheManager userCacheManage(RedisConnectionFactory connectionFactory) { Jackson2JsonRedisSerializer<Object> redisSerializer = new Jackson2JsonRedisSerializer<>(Object.class); ObjectMapper objectMapper = new ObjectMapper(); objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); redisSerializer.setObjectMapper(objectMapper); RedisCacheConfiguration cacheConfiguration = RedisCacheConfiguration.defaultCacheConfig() .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer)); RedisCacheManager redisCacheManager = RedisCacheManager.builder(connectionFactory).cacheDefaults(cacheConfiguration).build(); return redisCacheManager; }}Copy the code

Check the database. The database conversion is successful.