1. Overview

In this article, We will learn spring boot database cache example or configure cache in spring boot application. Spring provides spring caching module using that we can store objects inside the cache or memory. Let’s try to understand requirements of the database cache.

For example, Using different join or heavy database query that we fire in the database and fetch result If database result changes very rear so the database will return the same result every time in that it will be useless to fire query and fetch result  so the better way is the cache (using spring cache) result at the first time and return result from cache instead of executing query in database.

Generally, Application will cache Configuration, Email Templates, System properties so every time no need to fire query in the database. We need to take care that if value changes in database table at that time need to flush or clean caching.

We can also store cache based on conditions, here is the document for the conditional cache.

Steps to configure spring caching:

1. Add Spring Cache Dependency

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

2. Enable Caching

To enable caching add @EnableCaching annotation to spring configuration file. 

package com.javadeveloperzone;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.ComponentScan;
/**
 * Created by Java Developer Zone on 19-07-2017.
 */
@SpringBootApplication
@ComponentScan
@EnableCaching      // to enable spring cache
public class SpringBootConfig {
    public static void main(String[] args) throws Exception {
        SpringApplication.run(SpringBootConfig.class, args);    // run spring boot application          // it wil start application
    }
}

3. Cache & Clear value

  • Write @Cacheable annotation at method level which returns values. @Cacheable requires value parameter which indicates key of cachable value.
  • @CacheEvict annotation used for clean cache value. While add, update or delete the value in the database then we need to clear existing cache to the consistency of result.
    @Override
    @Cacheable(value="employees")           // it will cache result and key name will be "employees"
    public List<Employee> findAll() {
        return employeeDAO.findAll();
    }
    @Override
    @CacheEvict(value = "employees",allEntries = true)      // It will clear cache when delete any employee to database
    public void delete(long employeeId) {
        Employee employee = employeeDAO.findOne(employeeId);
        employeeDAO.delete(employee);
    }
    @Override
    @CacheEvict(value = "employees", allEntries=true)       // It will clear cache when new employee save to database
    public Employee save(Employee employee) {
        return employeeDAO.save(employee);
    }

4. Disable Cache

Set spring.cache.type to none to disable spring cache in application.properties

spring.cache.type=none

2. Example

Spring boot database cache example

Spring boot database cache example

2.1 pom.xml

  • spring-boot-starter-cache is for spring cache
  • spring-boot-starter-data-jpa is for spring JPA Hibernate
  • spring-boot-starter-web is for Spring MVC
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>spring-boot-example</groupId>
    <artifactId>Spring-boot-database-cache-example</artifactId>
    <version>1.0-SNAPSHOT</version>
    <description>Spring boot database cache example</description>
    <!-- Inherit defaults from Spring Boot -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.4.RELEASE</version>
    </parent>
    <properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.6</version>
        </dependency>
        <dependency>       <!-- spring cache dependency -->
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-cache</artifactId>
        </dependency>
    </dependencies>
    <!-- Package as an executable jar -->
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

2.2 application.properties

  • spring.datasource.* properties are related to database
  • spring.jpa.hibernate.* properties are related to hibernate.
spring.datasource.url=jdbc:mysql://localhost/demo_database
spring.datasource.username=root
spring.datasource.password=
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update
# Naming strategy
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
# Allows Hibernate to generate SQL optimized for a particular DBMS
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect

2.3 SpringBootConfig

  • @EnableCaching to enable spring caching
package com.javadeveloperzone;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.ComponentScan;
/**
 * Created by Java Developer Zone on 19-07-2017.
 */
@SpringBootApplication
@ComponentScan
@EnableCaching      // to enable spring cache
public class SpringBootConfig {
    public static void main(String[] args) throws Exception {
        SpringApplication.run(SpringBootConfig.class, args);    // run spring boot application          // it wil start application
    }
}

2.4 EmployeeService

package com.javadeveloperzone.service;
import com.javadeveloperzone.model.Employee;
import java.util.List;
/**
 * Created by JavaDeveloperZone on 04-04-2018.
 */
public interface EmployeeService {
    List<Employee> findAll();
    Employee save(Employee employee);
    void delete(long employeeId);
}

2.5 EmployeeServiceImpl

@Cacheable to enable the cache, It will cache the return value.

@CacheEvict to clean the cache, While perform add, update and delete operations will clear cache.

package com.javadeveloperzone.service;
import com.javadeveloperzone.dao.EmployeeDAO;
import com.javadeveloperzone.model.Employee;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import java.util.List;
/**
 * Created by JavaDeveloperZone on 04-04-2018.
 */
@Service
public class EmployeeServiceImpl implements EmployeeService {
    @Autowired
    private EmployeeDAO employeeDAO;
    @Override
    @Cacheable(value="employees")           // it will cache result and key name will be "employees"
    public List<Employee> findAll() {
        return employeeDAO.findAll();
    }
    @Override
    @CacheEvict(value = "employees",allEntries = true)      // It will clear cache when delete any employee to database
    public void delete(long employeeId) {
        Employee employee = employeeDAO.findOne(employeeId);
        employeeDAO.delete(employee);
    }
    @Override
    @CacheEvict(value = "employees", allEntries=true)       // It will clear cache when new employee save to database
    public Employee save(Employee employee) {
        return employeeDAO.save(employee);
    }
}

2.6 EmployeeDAO

package com.javadeveloperzone.dao;
import com.javadeveloperzone.model.Employee;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;

/**
 * Created by JavaDeveloperZone on 03-08-2017.
 */
@Repository
@Transactional
public interface EmployeeDAO extends CrudRepository<Employee,Long> {
    List<Employee> findAll();                           // fetch all Employee
}

2.7 EmployeeController

CacheManager is used to manage cache, like delete cache, view value etc.

package com.javadeveloperzone.controller;
import com.javadeveloperzone.model.Employee;
import com.javadeveloperzone.service.EmployeeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.CacheManager;
import org.springframework.web.bind.annotation.*;
/**
 * Created by JavaDeveloperZone on 19-07-2017.
 */
@RestController     // for rest response
public class EmployeeController {
    @Autowired
    private CacheManager cacheManager;      // autowire cache manager
    @Autowired
    private EmployeeService employeeService;
    // to add new employee
    @RequestMapping(value = "save",method = RequestMethod.POST)     // or user @GetMapping
    public Employee save(Employee employee){
        return employeeService.save(employee);
    }
    // list of all employee
    @RequestMapping(value = "listEmployee",method = RequestMethod.GET)   // or use @GetMapping
    public java.util.List<Employee> listEmployee() {
        return employeeService.findAll();
    }
    // delete specific employee using employee id
    @RequestMapping(value = "delete", method = RequestMethod.DELETE)        // or use @DeleteMapping
    public void delete(@RequestParam("id")long id){
         employeeService.delete(id);
    }
    // clear all cache using cache manager
    @RequestMapping(value = "clearCache")
    public void clearCache(){
        for(String name:cacheManager.getCacheNames()){
            cacheManager.getCache(name).clear();
        }
    }
}

2.8 Employee

package com.javadeveloperzone.model;
import javax.persistence.*;
/**
 * Created by Java Developer Zone on 03-08-2017.
 */
@Entity
@Table(name = "employee")
public class Employee {
    @Id                                                     // primary key
    @GeneratedValue(strategy = GenerationType.IDENTITY)     // auto increment
    @Column(name = "employeeId")
    private long employeeId;
    @Column(name = "employeeName")
    private String employeeName;
    @Column(name = "employeeRole")
    private String employeeRole;
    public long getEmployeeId() {
        return employeeId;
    }
    public void setEmployeeId(long employeeId) {
        this.employeeId = employeeId;
    }
    public String getEmployeeRole() {
        return employeeRole;
    }
    public void setEmployeeRole(String employeeRole) {
        this.employeeRole = employeeRole;
    }
    public String getEmployeeName() {
        return employeeName;
    }
    public void setEmployeeName(String employeeName) {
        this.employeeName = employeeName;
    }
}

Demo

  •  While fetching the list of Employee first time it will fetch from the database but the second time it will fetch from the cache.
  •  While delete or add new Employee existing cache will be clear.

localhost:8080/listEmployee

Spring boot database cache example - List Employee

Spring boot database cache example – List Employee

First time from the database:

Hibernate: select employee0_.employeeId as employee1_0_, employee0_.employeeName as employee2_0_, employee0_.employeeRole as employee3_0_ from employee employee0_

3. Conclusion

In this article, We learn how we can configure spring cache in spring boot database application. The cache will be helpful to improve the performance of the application. Need to take care while using cache in the application, Any data update in the database need to consist that value in cache also otherwise change of database inconsistency in application.

4. References

5. Source Code

spring-boot-database-cache-example (53 KB)

Was this post helpful?

3 comments. Leave new

Awesome! I have a question, how much time cached data will be alive? Where can we set that configuration.

Hi,

You can set cron job to clear all cache for the particular time limit, You can refer our article for same.

https://javadeveloperzone.com/spring-boot/spring-cache-clear-all-cache/

It will not cache data until you clear it. Spring cache has not defined any default policy to clear cache automatically. You can also use any other third party for caching mechanisms.

Leave a Reply

Your email address will not be published. Required fields are marked *