Spring boot应用中如何在应用启动时缓存数据

问题描述 投票:0回答:5

我有一个连接到 SQL Server 数据库的 Spring boot 应用程序。我需要一些帮助来在我的应用程序中使用缓存。我有一个 CodeCategory 表,其中包含许多代码的代码列表。该表将每月加载一次,并且数据每月仅更改一次。 我想在应用程序启动时缓存整个表。在对表的任何后续调用中,都应该从此缓存中获取值,而不是调用数据库。

例如,

List<CodeCategory> findAll();

我想在应用程序启动期间缓存上述数据库查询值。如果有像

List<CodeCategory> findByCodeValue(String code)
这样的数据库调用,应该从已经缓存的数据中获取代码结果,而不是调用数据库。

请让我知道如何使用 spring boot 和 ehcache 来实现这一点。

java spring spring-boot caching ehcache
5个回答
3
投票

正如所指出的,ehcache 需要一些时间来设置,并且它不能完全与

@PostConstruct
一起工作。在这种情况下,请使用
ApplicationStartedEvent
加载缓存。

GitHub 存储库: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);
}


注意:其他人指出有多种方法。您可以根据您的需要进行选择。


2
投票

我的方法是定义一个通用的缓存处理程序

@FunctionalInterface
public interface GenericCacheHandler {

List<CodeCategory> findAll();
 }

其实现如下

@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;
}
}

Service层调用如下

@Service
public class CodeServiceImpl implements CodeService {

@Autowired
private GenericCacheHandler genericCacheHandler;

@Override
public CodeDTO anyMethod() {
    return genericCacheHandler.getCodes();
}   
}

0
投票

使用二级休眠缓存来缓存所有需要的数据库查询。

为了在应用程序启动时进行缓存,我们可以在任何 Service 类中使用@PostContruct。

语法为:-

@Service
public class anyService{

  @PostConstruct
  public void init(){
     //call any method
 }
}

0
投票

使用 CommandLineRunner 界面。 基本上,您可以创建一个 Spring @Component 并实现 CommandLineRunner 接口。您必须重写它的 run 方法。 run 方法将在应用程序启动时调用。

@Component
public class DatabaseLoader implements 
CommandLineRunner {

   @override
   Public void run(.... string){
     // Any code here gets called at the start of the app.
  }}

此方法主要用于使用一些初始数据引导应用程序。


0
投票
    @Service
    public class ProductService {

    @Autowired
    private ProductRepository productRepository;

    public List<Product> getAllProducts() {
        return productRepository.findAll();
    }

    @Cacheable(cacheNames = "product", key = "#id")
    public ProductDto findById(Long id) {
        Product savedProduct = productRepository.findById(id).orElseThrow(() -> new RuntimeException("Product not found"));
        ProductDto productDto = new ProductDto();
        BeanUtils.copyProperties(savedProduct, productDto);
        return productDto;
    }

}
© www.soinside.com 2019 - 2024. All rights reserved.