Note: This article was first published on CodeSheep · Program Sheep. Welcome to the site!

This article contains 851 words and takes about 3 minutes to read!

The brain map of this paper is as follows:


An overview of the

In today’s highly concurrent Internet applications, cache plays an important role in improving program performance. Spring also introduced Cache support with 3.x, which is certainly a feature that Spring Boot supports today. Of course Spring Boot default SimpleCacheConfiguration, which USES ConcurrentMapCacheManager to implement caching. But this article will show you how to apply Ehcache caching to your Spring Boot application.

“Ehcache” is an open source cache management library based on Java implementation, which provides flexible management solutions such as memory, disk file storage, and distributed storage. The usage and principles are somewhat similar to Spring transaction management and are easy to use with annotations.

Here is a hand to touch it, combined with the database operation, we let Ehcache as a local cache to see the effect!


The preparatory work

  • Prepare the database and tables and insert the corresponding data (MySQL)

For example, I have prepared a user table with several records:

We will simulate database access to see the effect of the Ehcache.


Springboot + MyBatis + MySQL + Ehcache

Add the following dependencies to pom.xml:

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <! --for mybatis-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.3.2</version>
        </dependency>

        <! --for Mysql-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>

        <! -- Spring boot Cache-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-cache</artifactId>
        </dependency>

        <! --for ehcache-->
        <dependency>
            <groupId>net.sf.ehcache</groupId>
            <artifactId>ehcache</artifactId>
        </dependency>

    </dependencies>
Copy the code

Create an Ehcache profile

Create Ehcache configuration file ehcache.xml and place it in the project classpath:

<?xml version="1.0" encoding="UTF-8"? >
<ehcache>

    <diskStore path="java.io.tmpdir"/>

    <! -- Set default data expiration policy for cache -->
    <defaultCache
            maxElementsInMemory="10000"
            eternal="false"
            timeToIdleSeconds="120"
            timeToLiveSeconds="120"
            overflowToDisk="true"
            maxElementsOnDisk="10000000"
            diskPersistent="false"
            diskExpiryThreadIntervalSeconds="120"
            memoryStoreEvictionPolicy="LRU"/>

    <cache name="user"
           maxElementsInMemory="1000"
           eternal="false"
           timeToIdleSeconds="10"/>

</ehcache>
Copy the code

Configure the application. The properties

server.port=80

Mysql data source configurationSpring. The datasource. Url = JDBC: mysql: / / 121.196.213.251:3306 / demo? useUnicode=true&characterEncoding=utf-8&useSSL=false
spring.datasource.username=root
spring.datasource.password=xxxxxx
spring.datasource.driver-class-name=com.mysql.jdbc.Driver

# mybatis configuration
mybatis.type-aliases-package=cn.codesheep.springbt_ehcache.entity
mybatis.mapper-locations=classpath:mapper/*.xml
mybatis.configuration.map-underscore-to-camel-case=true

# ehcache configuration
spring.cache.ehcache.config=classpath:ehcache.xml
Copy the code

Write business code to operate the database and Ehcache

  • Write the entity
public class User {

    private Long userId;
    private String userName;
    private Integer userAge;

    public Long getUserId() {
        return userId;
    }

    public void setUserId(Long userId) {
        this.userId = userId;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public Integer getUserAge() {
        return userAge;
    }

    public void setUserAge(Integer userAge) { this.userAge = userAge; }}Copy the code
  • Write the mapper
public interface UserMapper {

    List<User> getUsers();

    int addUser(User user);

    List<User> getUsersByName( String userName );
}
Copy the code
  • Write the service
@Service
public class UserService {

    @Autowired
    private UserMapper userMapper;

    public List<User> getUsers() {
        return userMapper.getUsers();
    }

    public int addUser( User user ) {
        return userMapper.addUser(user);
    }

    @Cacheable(value = "user", key = "#userName")
    public List<User> getUsersByName( String userName ) {
        List<User> users = userMapper.getUsersByName( userName );
        System.out.println( "Read from database, not cache!" );
        returnusers; }}Copy the code

As you can see, we’ve annotated the getUsersByName interface with @cacheable. This is one of the more common Ehcache annotations, along with @cacheput and @cacheevit.

  1. @Cacheable: configuration ingetUsersByNameMethod to indicate that its return value will be added to the cache. At the same time, during the query, the database will be obtained from the cache first. If the database does not exist, the access to the database will be initiated
  2. @CachePutWhen configured on a method, it can be cached according to parameters defining conditions@CacheableThe difference is the use@CachePutThe annotated method does not check the existence of the previously executed result in the cache before execution. Instead, the method is executed each time and the execution result is stored in the specified cache in the form of key-value pairs, so it is mainly used for data addition and modification operations
  3. @CacheEvict: Removes data from the cache when configured on a method.
  • Writing the controller
@RestController
public class UserController {

    @Autowired
    private UserService userService;

    @Autowired
    CacheManager cacheManager;

    @GetMapping("/users")
    public List<User> getUsers() {
        return userService.getUsers();
    }

    @GetMapping("/adduser")
    public int addSser() {
        User user = new User();
        user.setUserId(4l);
        user.setUserName("Zhao four");
        user.setUserAge(38);
        return userService.addUser(user);
    }

    @RequestMapping( value = "/getusersbyname", method = RequestMethod.POST)
    public List<User> geUsersByName( @RequestBody User user ) {
        System.out.println( "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --" );
        System.out.println("call /getusersbyname");
        System.out.println(cacheManager.toString());
        List<User> users = userService.getUsersByName( user.getUserName() );
        returnusers; }}Copy the code

Modify the Main SpringBoot application class

This is mainly done by explicitly enabling Ehcache caching on the startup class via the @enablecaching annotation

@SpringBootApplication
@MapperScan("cn.codesheep.springbt_ehcache") @EnableCaching public class SpringbtEhcacheApplication { public static void main(String[] args) { SpringApplication.run(SpringbtEhcacheApplication.class, args); }}Copy the code

The final structure of the project is as follows:


The actual experiment

To the interface through multiple localhost/getusersbynamePOST data to observe effect:

You can see the effect of the cache being enabled and deactivated (ehCache configuration file above).


Remember after

Due to the limited ability, if there is a mistake or improper place, please also criticize and correct, study together!

  • My Personal Blog: CodeSheep program sheep
  • My six months of tech blogging

The experimental code of this paper is here



To subscribe to CodeSheep’s public account, long press or scan below, you can get more practical, understandable and reproducible original articles