Over time , The number of users of applications is increasing , The data scale is getting bigger and bigger , Database query operation often becomes the bottleneck of user experience , At this time, using cache is often one of the best ways to solve this problem .Spring 3 Started with powerful annotation based caching support , You can use annotation configuration to provide low intrusion to the original Spring Application added cache function , Improve data access performance .
stay Spring Boot Cache support in , Provides a range of automated configurations , So we can use the cache very conveniently . Let’s use a simple example to show , How do we add caching to an existing application .
Quick start
We will use Use Spring Data JPA visit MySQL Based on the case of this article . This case involves the use of Spring Data JPA visit User Data operation , Use this foundation , We add a cache to it , To reduce the amount of IO, In order to achieve the function of Access Acceleration . If you are not familiar with how to implement to MySQL Read and write operations , So it’s suggested to read the previous article first , Complete the basic case .
Let’s briefly review the basic content of this case :
User Definition of entity
@Entity
@Data
@NoArgsConstructor
public class User {
@Id
@GeneratedValue
private Long id;
private String name;
private Integer age;
public User(String name, Integer age) {
this.name = name;
this.age = age;
}
}
User Entity data access implementation
public interface UserRepository extends JpaRepository<User, Long> {
User findByName(String name);
User findByNameAndAge(String name, Integer age);
@Query("from User u where u.name=:name")
User findUser(@Param("name") String name);
}
To better understand caching , Let’s make some simple modifications to the project first .
application.properties
Add… To the filespring.jpa.show-sql=true
, Turn on hibernate Yes sql The printing of statements . If it is 1.x edition , Usespring.jpa.properties.hibernate.show_sql=true
Parameters .- Modify unit test classes , Insert User The user name in Table 1 is AAA, Age is 10 The data of . And pass findByName Function to complete two queries , The specific code is as follows :
@RunWith(SpringRunner.class)
@SpringBootTest
public class Chapter51ApplicationTests {
@Autowired
private UserRepository userRepository;
@Test
public void test() throws Exception {
// establish 1 Bar record
userRepository.save(new User("AAA", 10));
User u1 = userRepository.findByName("AAA");
System.out.println(" First query :" + u1.getAge());
User u2 = userRepository.findByName("AAA");
System.out.println(" Second query :" + u2.getAge());
}
}
Before the cache is added , We can run this case first , You can see the following log :
Hibernate: select user0_.id as id1_0_, user0_.age as age2_0_, user0_.name as name3_0_ from user user0_ where user0_.name=?
First query :10
Hibernate: select user0_.id as id1_0_, user0_.age as age2_0_, user0_.name as name3_0_ from user user0_ where user0_.name=?
Second query :10
two findByName
The query was executed twice SQL, All right. MySQL Database query .
Introduce caching
First step : stay pom.xml
Introduction in cache rely on , Add the following :
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
The second step : stay Spring Boot Add… To the main class @EnableCaching
Annotations enable caching , as follows :
@EnableCaching
@SpringBootApplication
public class Chapter51Application {
public static void main(String[] args) {
SpringApplication.run(Chapter51Application.class, args);
}
}
The third step : In the data access interface , Add cache configuration comments , Such as :
@CacheConfig(cacheNames = "users")
public interface UserRepository extends JpaRepository<User, Long> {
@Cacheable
User findByName(String name);
}
Step four : And then perform the following unit tests , You can output the following content in the console
Hibernate: insert into user (age, name, id) values (?, ?, ?)
Hibernate: select user0_.id as id1_0_, user0_.age as age2_0_, user0_.name as name3_0_ from user user0_ where user0_.name=?
First query :10
Second query :10
Come here , We can see , Call the second time findByName
Function time , No more execution select sentence , It also directly reduces a database read operation .
For better observation , Cache storage , We can inject CacheManager
.
@Autowired
private CacheManager cacheManager;
Use debug Mode run unit test , Observe CacheManager
Cache set in users And some of them User Object caching helps understand .
You can see , On the first call findByName
After the function ,CacheManager
Save the query result , So on the second visit , You can match without having to access the database again .
Cache Configuration annotation details
Let’s go back to what the two annotations used here do :
@CacheConfig
: It is mainly used to configure some common cache configurations used in this class . ad locum@CacheConfig(cacheNames = "users")
: If the data access object is configured, the returned content will be stored in the name of users In the cache object of , We can also not use the annotation , Directly through@Cacheable
Configure the name of the cache set to define it .@Cacheable
: Configured with findByName The return value of the function will be added to the cache . At the same time, when querying , Will get from the cache first , If it does not exist, it will initiate access to the database . The annotation has the following parameters :value
、cacheNames
: Two identical parameters (cacheNames
by Spring 4 newly added , Asvalue
Another name for ), The collection name used to specify the cache store . because Spring 4 Added in@CacheConfig
, So in Spring 3 The Central Plains must havevalue
attribute , It has become a non essential itemkey
: Objects are stored in the Map In the collection key value , Non essential , By default, all parameters of the function are combined as key value , If you configure it yourself, you need to use SpEL expression , such as :@Cacheable(key = "#p0")
: Using the first parameter of the function as the cached key value , More about SpEL For details of the expression, please refer to Official documentscondition
: Conditions for caching objects , Non essential , Also use SpEL expression , Only content that satisfies the expression condition is cached , such as :@Cacheable(key = "#p0", condition = "#p0.length() < 3")
, Only if the length of the first parameter is less than 3 Only when it’s cached , If you do this configuration above AAA Users will not be cached , Readers can experiment with it .unless
: Another cache condition parameter , Non essential , Need to use SpEL expression . It is different fromcondition
The parameter’s place is its judgment timing , The condition is judged after the function is called , So it can be done by result Judge .keyGenerator
: Is used to specify the key generator , Non essential . If you need to specify a custom key generator , We need to achieveorg.springframework.cache.interceptor.KeyGenerator
Interface , And use this parameter to specify . It should be noted that : The parameter andkey
They are mutually exclusive.cacheManager
: Specifies which cache manager to use , Non essential . Use only when there are more than onecacheResolver
: Used to specify which cache parser to use , Non essential . Need to passorg.springframework.cache.interceptor.CacheResolver
Interface to implement your own cache parser , And use this parameter to specify .
In addition to the two annotations used here , And here are some core notes :
@CachePut
: Configure on function , It can cache according to the parameters , It is associated with@Cacheable
The difference is , Every time it really calls a function , So it is mainly used for data addition and modification . Its parameters are similar to@Cacheable
similar , Specific functions can refer to the face of@Cacheable
Parameter parsing@CacheEvict
: Configure on function , It’s usually used in deletion methods , Used to remove the corresponding data from the cache . Except for the same@Cacheable
Besides the same parameters , It also has the following two parameters :allEntries
: Non essential , The default is false. When it comes to true when , It will remove all the databeforeInvocation
: Non essential , The default is false, The data is removed after the method is called . When it comes to true when , The data is removed before the method is called .
Code example
For an example of this article, see the following in the warehouse chapter5-1
Catalog :
- Github:https://github.com/dyc87112/SpringBoot-Learning/
- Gitee:https://gitee.com/didispace/SpringBoot-Learning/
If you think this article is good , welcome Star
Support , Your concern is the driving force of my persistence !
First article :Spring Boot 2.x Basic course : The use of in-process cache and Cache Annotations, , Reprint please indicate the source . Welcome to my official account. : Program the ape DD, Get exclusive learning resources and daily dry goods push . If you are interested in my other topics , Direct to my personal blog :didispace.com.