Why cache? I don’t want to explain too much here, we have touched both mobile and front-end! Redis is a lightweight key-value database, similar to SP on Android or localStorage in the front end. It is to put the data to be cached into key-value pairs. When used, the value can be retrieved through key and directly cached, so that there is no need to call the interface or query the database again. Understand that, and you’ll feel much simpler!
GitHub:github.com/baiyuliang/…
Pom. XML is introduced into:
<! --redis-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<version>2.3.4. RELEASE</version>
</dependency>
Copy the code
Application. Yml adds redis configuration:
spring:
redis:
host: 39.xxx.x.xx
port: 6379
database: 1 # redis16 which library, default 0
client-name: redis
password: 123456
timeout: 3000 Connection timeout (ms)
jedis.pool.max-active: 8 Redis maximum number of connections in the connection pool
jedis.pool.max-idle: 8 # Redis maximum number of free connections in the connection pool
jedis.pool.max-wait: - 1 The maximum waiting time in the connection pool of redis, -1, indicates that there is no limit
jedis.pool.min-idle: 0 The minimum number of free connections in redis connection pool
Copy the code
Create RedisConfig:
package com.byl.springboottest.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import java.time.Duration;
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<Object, Object> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
Jackson2JsonRedisSerializer<Object> serializer = new Jackson2JsonRedisSerializer<>(Object.class);
template.setDefaultSerializer(serializer);
return template;
}
@Bean
public RedisCacheManager redisCacheManager(RedisConnectionFactory redisConnectionFactory) {
RedisCacheConfiguration cacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofDays(1))
.disableCachingNullValues()
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()));
returnRedisCacheManager.builder(redisConnectionFactory).cacheDefaults(cacheConfiguration).build(); }}Copy the code
Start testing:
1. EnableCaching @enablecaching: Application entry:
@EnableCaching// Enable caching
@SpringBootApplication
public class SpringboottestApplication {
public static void main(String[] args) { SpringApplication.run(SpringboottestApplication.class, args); }}Copy the code
2. Add @cacheable annotation to a method of the Service:
@Service
public class UserServiceImpl implements UserService {
@Resource
UserRepository userRepository;
@Cacheable(cacheNames = "user", condition = "#id>0", unless = "#result==null")
@Override
public User getUserById(Integer id) {
return userRepository.getOne(id);
}
@Override
public User getUserByName(String username) {
returnuserRepository.findByUserName(username); }}Copy the code
The cacheNames cache name, the condition cache condition (only id>0 is cached), and unless is also a cache condition, but it is not cached if it is valid.
Run the project, the browser input: http://localhost:8080/byl/user/2, to test the corresponding method of cache:
First run result:
Console:
That the first time from the database query without error!
View Redis database:
Cache successful!
I’ll change my browser and run it again:
At this point, the console does not print any Sql data, indicating that Redis has been successfully integrated!
When we need to update the cache, we can add @cacheput to a method and remove the cache with @cacheevict!
To use @cacheable, you should declare cacheNames, which is to separate your cache information from other Cacheable information. You can use the same type of business in a unified module, such as user, to query information in Redis:
Specify another name, and the corresponding folder will be generated!
User ::2 is the key, because if we do not specify a key, the cache will automatically store the parameter value as the key. We can use the keyGenerator property to customize the key generation mechanism, but note that the key values stored must be regular. So when you update or delete the cache, you can cache the data exactly by the corresponding key operation!
Here is an example of a custom keyGenerator:
@Configuration
public class MyCacheConfig {
@Bean("myKeyGenerator")
public KeyGenerator keyGenerator(a) {
return new KeyGenerator() {
@Override
public Object generate(Object o, Method method, Object... objects) {
return method.getName() + "[" + Arrays.asList(objects).toString() + "]"; }}; }}Copy the code
Use the method name and parameters as keys!
To reference this keyGenerator:
@Cacheable(cacheNames = "user", condition = "#id>0", unless = "#result==null" ,keyGenerator = "myKeyGenerator")
Copy the code
If we declare @cacheable directly on a method, we will cache the results of the method by default. In real development, in the Service layer, methods return results with a fixed-format data model, such as:
{
code:1.msg:"Succeeded in getting the list".data: {total:1.list:[{...}]}}Copy the code
This may not meet our actual needs, because we only want to cache the data from the database, not the data returned by the business layer. In this case, we can directly use the code to cache data access:
@Resource
RedisCacheManager redisCacheManager;// Cache manager
// @Cacheable(cacheNames = "user",condition = "#id>0", unless = "#result==null")
@Override
public User getUserById(Integer id) {
User user;
Cache cache = redisCacheManager.getCache("user");//cacheNames
if (cache.get("getUserById"+ id) ! =null) {
user = (User) cache.get("getUserById" + id).get();// Get value by key
if(user ! =null) {
System.out.println("Get result from cache >>" + user.getNickName());
return user;
}
}
user = userRepository.findById(id).get();
cache.put("getUserById" + id, user);// Cache data
return user;
}
Copy the code
We first empty redis database, then run the program, the browser input: http://localhost:8080/byl/user/2
View redis database:
Refresh the browser again:
Of course, there are n more methods to cache, which you can use when appropriate: