Spring Boot服务重载后如何保留H2数据库中的代码片段数据
解决方案
你的问题根源为:业务层SnippetService仅在新增代码片段时同步写入内存缓存和数据库,服务重载后内存缓存被清空,未从持久化的H2文件数据库加载历史数据,导致接口无法返回已存储的内容。
具体修改步骤
1. 调整SnippetService逻辑,新增启动初始化加载
给SnippetService注入Repository依赖,新增@PostConstruct注解的初始化方法,服务启动时自动读取数据库所有已存代码片段加载到内存缓存中,同时将数据库写入逻辑收敛到Service层降低耦合:
@Service public class SnippetService { @Autowired private Repository snippetRepository; // 此处替换为你实际使用的内存存储结构(List/Map均可) private final Map<Integer, Snippet> snippetCache = new HashMap<>(); // 服务启动完成后自动执行该方法,从数据库加载所有历史数据到内存 @PostConstruct public void loadDataFromDBOnStart() { List<Snippet> allSnippets = snippetRepository.findAll(); allSnippets.forEach(snippet -> snippetCache.put(snippet.getId(), snippet)); } // 新增片段逻辑调整为:先存数据库,再更新内存缓存 public int addSnippet(Snippet snippet) { Snippet savedSnippet = snippetRepository.save(snippet); snippetCache.put(savedSnippet.getId(), savedSnippet); return savedSnippet.getId(); } // 剩余getSnippet、getLatestSnippets方法保持原有逻辑,从内存缓存读取即可 public Snippet getSnippet(int id) { return snippetCache.get(id); } public List<Snippet> getLatestSnippets() { return snippetCache.values().stream() // 按时间倒序取最新10条,可根据你的实际需求调整排序和数量规则 .sorted(Comparator.comparing(Snippet::getCreateTime).reversed()) .limit(10) .collect(Collectors.toList()); } }
2. 清理控制器冗余代码
删除控制器中直接操作Repository的逻辑,避免重复操作和逻辑分散:
@Controller public class SnippetController { @Autowired SnippetService snippetService; // 移除Repository的注入,所有数据库操作都收敛到Service层 // 构造方法保持不变 public SnippetController(SnippetService snippetService) { this.snippetService = snippetService; } // 其余接口方法保持不变,仅修改新增接口的逻辑 @PostMapping(value = "/api/code/new") @ResponseBody public Map<String, String> addSnippet(@RequestBody Snippet snippet) { int id = snippetService.addSnippet(snippet); // 移除原来的repository.save(snippet)调用 return Map.of("id", String.valueOf(id)); } // 剩余get、show相关方法保持不变即可 }
必要校验项
- 确认你的Snippet实体类主键id字段添加了
@Id和@GeneratedValue(strategy = GenerationType.IDENTITY)注解,保证数据库自动生成唯一主键 - 确认
application.properties中spring.jpa.hibernate.ddl-auto配置保持为update,不要修改为create或create-drop,否则服务重启会清空数据表 - 确认H2数据文件路径
../snippetsOfCode有读写权限,不会因为路径权限问题导致数据丢失
内容的提问来源于stack exchange,提问作者Staaankey
相关产品推荐
相关产品推荐

