如何使用 Thymeleaf 在 Spring Boot 应用程序中正确缓存数据

Posted

技术标签:

【中文标题】如何使用 Thymeleaf 在 Spring Boot 应用程序中正确缓存数据【英文标题】:How to properly cache data in spring boot application with Thymleaf 【发布时间】:2020-02-14 20:20:40 【问题描述】:

我正在为我的 Spring 引导应用程序编写一些 Java 代码,以接收 40,000 个元素的列表,并通过 Thymeleaf 将其发布到下拉字段中。但是,我注意到当我加载数据并转到下拉列表时,一切都很慢。

有人告诉我缓存这些值并存储它们。虽然我对这个过程不太熟悉,但我尝试为我的 SpringBootApplication 使用 @Cacheable 注释,但它仍然不起作用。我想看看我做错了什么,或者是否有更好的方法来解决我遇到的这个问题。

服务层:

@SuppressWarnings("unchecked")
@Cacheable("String")
public List<String> getServerListing()
    StoredProcedureQuery storedProcedure = entityManager.createStoredProcedureQuery("GetAllServers");
    return storedProcedure.getResultList();


首先,我有一个存储过程会从服务器中删除所有数据(约 40,000 条记录)。

控制器:

List<String> servers = joinQueryService.getServerListing();

modelAndView.addObject("servers", servers);

然后,我将其设置为字符串列表并将其发送到前端。

百里香:

<div class="row">
    <div class="col col-lg-9 search-bar">
        <div class="form-group">
            <label>Server:</label> <select class="js-example-basic-single3"
                th:field="*servers" id="selectData3">
                <option value=""></option>
                <option th:each="servers : $servers" th:value="$servers" th:text="$servers" />
            </select>

        </div>
    </div>
</div>

SpringBoot:

@SpringBootApplication
@Cacheable
public class TaddmDevApplication 

    public static void main(String[] args) 

        Policy.setPolicy(new TaddmPolicy());

        SpringApplication.run(TaddmDevApplication.class, args);
    


【问题讨论】:

一切都很慢...有多慢?假设数据确实被缓存了(当然是在从数据库第一次加载之后),我很好奇在浏览器中渲染 40,000 条记录下拉列表花费了多少时间。例如,Chrome DevTools(或 FF/Edge 的类似工具)可以阐明这一点。 @andrewjames 所以在使用 Chrome 开发工具查看后,它显示加载大约需要 4 - 5 秒。如果可能的话,我的目标是将其减少到毫秒。 【参考方案1】:

我认为这里的问题是:浏览器将需要几秒钟来加载和/或显示如此大的下拉菜单,无论您的应用程序的其余部分如何精简。

作为测试,我创建了一个文本文件,除了包含 40,000 项的下拉列表 (test.htm) 之外什么都不包含:

<!DOCTYPE html>
<html>
<body>
<h2>Create a drop-down List</h2>

<label for="widgets">Choose a widget:</label>

<select id="widgets">
  <option value="widget1">Widget 1</option>
  <option value="widget2">Widget 2</option>
  <option value="widget3">Widget 3</option>
  <option value="widget4">Widget 4</option>
  <option value="widget5">Widget 5</option>
  <option value="widget6">Widget 6</option>
  <option value="widget7">Widget 7</option>
  ... snipped for brevity!
  <option value="widget39998">Widget 39998</option>
  <option value="widget39999">Widget 39999</option>
  <option value="widget40000">Widget 40000</option>
</select>

</body>
</html>

然后我在 Chrome 中打开该文件并记录处理时间:

大约需要 5 秒钟。没有数据库获取;没有网络流量;没有服务器端处理。

我认为底线是:这种大小的下拉菜单对于用户来说会很笨拙,并且在浏览器中处理 会很慢。

这意味着您的问题变成了另一个问题:如何向浏览器发送更少量的数据,并允许用户一次浏览一页浏览每次加载的结果。顺便说一句,我完全同意你的“毫秒”目标,而不是秒。这是完全正确的。也许您已经有了一个,但请尝试记住一个特定的目标(“低于 300 毫秒”或类似的目标)。

当然,您的代码中可能会有优化 - 但目前可能还没有实际意义。

可能不是您想要的答案,但我希望这会有所帮助!

【讨论】:

是的,这对我有帮助,我将继续对此进行研究。如果您认为或知道任何可能有帮助的方法,请告诉我。如果没有,我会继续阅读。再次感谢您的帮助和建议。 我不使用 Spring,但我确信它必须提供良好的 support for paging。祝你好运。

以上是关于如何使用 Thymeleaf 在 Spring Boot 应用程序中正确缓存数据的主要内容,如果未能解决你的问题,请参考以下文章

如何使用Thymeleaf在Spring中配置CharacterEncodingFilter?

如何使用 Thymeleaf 在 Spring Boot 应用程序中正确缓存数据

如何在 Spring Thymeleaf 中提交表格数据

如何使用 Thymeleaf 配置 Spring Boot 并使用 sec:authentication 标签

如何使用 Spring 和 Thymeleaf 在下拉列表中显示所有可能的枚举值?

如何使用 Thymeleaf 或 JSP 在 Spring Boot 中启用目录列表