[英]How to cache data during application startup in Spring boot application
I have a Spring boot Application connecting to SQL Server Database. 我有一个连接到SQL Server数据库的Spring启动应用程序。 I need some help in using caching in my application. 在我的应用程序中使用缓存需要一些帮助。 I have a table for CodeCategory which has a list of codes for Many codes. 我有一个CodeCategory表,其中包含许多代码的代码列表。 This table will be loaded every month and data changes only once in a month. 此表将每月加载一次,数据仅在一个月内更改一次。 I want to cache this entire table when the Application starts. 我想在应用程序启动时缓存整个表。 In any subsequent calls to the table should get value from this cache instead of calling the Database. 在对表的任何后续调用中,应从此缓存中获取值,而不是调用数据库。
For Example, 例如,
List<CodeCategory> findAll();
I want to cache the above DB query value during application startup. 我想在应用程序启动期间缓存上面的数据库查询值。 If there is a DB call like List<CodeCategory> findByCodeValue(String code)
should fetch the code result from the already Cached data instead of calling the Database. 如果存在类似List<CodeCategory> findByCodeValue(String code)
的DB调用,则List<CodeCategory> findByCodeValue(String code)
应从已缓存的数据中获取代码结果,而不是调用数据库。
Please let me know how this can be achieved using spring boot and ehcache. 请告诉我如何使用spring boot和ehcache实现这一目标。
Use the second level hibernate caching to cache all the required db queries. 使用二级hibernate缓存来缓存所有必需的数据库查询。
For caching at the application start-up, we can use @PostContruct in any of the Service class. 对于应用程序启动时的缓存,我们可以在任何Service类中使用@PostContruct。
Syntax will be :- 语法将是: -
@Service
public class anyService{
@PostConstruct
public void init(){
//call any method
}
}
As pointed out, It takes some time for ehcache to setup and it is not working completely with @PostConstruct
. 正如所指出的,ehcache设置需要一些时间,并且它与@PostConstruct
完全不兼容。 In that case make use of ApplicationStartedEvent
to load the cache. 在这种情况下,请使用ApplicationStartedEvent
来加载缓存。
GitHub Repo: spring-ehcache-demo GitHub Repo: spring-ehcache-demo
@Service
class CodeCategoryService{
@EventListener(classes = ApplicationStartedEvent.class )
public void listenToStart(ApplicationStartedEvent event) {
this.repo.findByCodeValue("100");
}
}
interface CodeCategoryRepository extends JpaRepository<CodeCategory, Long>{
@Cacheable(value = "codeValues")
List<CodeCategory> findByCodeValue(String code);
}
Note: There are multiple ways as pointed by others. 注意:其他方式有多种方式。 You can choose as per your needs. 您可以根据自己的需要进行选择。
Use CommandLineRunner interface. 使用CommandLineRunner接口。 Basically , you can create a Spring @Component and implement CommandLineRunner interface. 基本上,您可以创建Spring @Component并实现CommandLineRunner接口。 You will have to override it's run method. 你必须覆盖它的run方法。 The run method will be called at the start of the app. 将在应用程序启动时调用run方法。
@Component
public class DatabaseLoader implements
CommandLineRunner {
@override
Public void run(.... string){
// Any code here gets called at the start of the app.
}}
This approach is mostly used to bootstrap the application with some initial data. 此方法主要用于使用一些初始数据引导应用程序。
My way is to define a generic cache handler 我的方法是定义一个通用的缓存处理程序
@FunctionalInterface
public interface GenericCacheHandler {
List<CodeCategory> findAll();
}
And its implementation as below 其实施如下
@Component
@EnableScheduling // Important
public class GenericCacheHandlerImpl implements GenericCacheHandler {
@Autowired
private CodeRepository codeRepo;
private List<CodeCategory> codes = new ArrayList<>();
@PostConstruct
private void intializeBudgetState() {
List<CodeCategory> codeList = codeRepo.findAll();
// Any customization goes here
codes = codeList;
}
@Override
public List<CodeCategory> getCodes() {
return codes;
}
}
Call it in Service layer as below 在Service层中调用它,如下所示
@Service
public class CodeServiceImpl implements CodeService {
@Autowired
private GenericCacheHandler genericCacheHandler;
@Override
public CodeDTO anyMethod() {
return genericCacheHandler.getCodes();
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.