springboot集成h2数据库并使用多数据源

news/2024/12/17 22:25:36/

前言

为了满足客户的需求,我们计划将项目中使用的MySQL数据库迁移至H2数据库。虽然项目已经集成了多数据源,理论上可以正常运作,但在实际操作过程中,我们发现项目启动时无法自动创建表。我们将对此问题进行深入分析,并寻找合适的解决方案以确保项目的顺利运行。

实战

调整依赖

新增h2数据库依赖

<!-- dynamic-datasource 多数据源-->
<dependency><groupId>com.baomidou</groupId><artifactId>dynamic-datasource-spring-boot-starter</artifactId><version>${dynamic-ds.version}</version>
</dependency>
<!-- mybatisPlus-->
<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>${mybatis-plus.version}</version>
</dependency>
<!-- h2数据库 -->
<dependency><groupId>com.h2database</groupId><artifactId>h2</artifactId><version>${h2.version}</version>
</dependency>

配置文件

在我们的项目配置中,由于选择了本地连接方式,因此数据库的URL被特意设置为指向本地路径。这样的安排旨在确保数据访问的便捷性和效率,同时也便于管理和维护数据库资源。

--- # 数据源配置
spring:h2:# 嵌入式(本地)连接file_path: D:/H2/db/ # 数据库路径db_name: park # 数据库名称console:path: /h2 # 通过YOUR_URL:PORT/h2访问h2 web consloeenabled: true # 程序开启时就会启动h2 web consloedatasource:type: com.zaxxer.hikari.HikariDataSource# 动态数据源文档dynamic:# 性能分析插件(有性能损耗 不建议生产环境使用)p6spy: true# 设置默认的数据源或者数据源组,默认值即为 masterprimary: master# 严格模式 匹配不到数据源则报错strict: truedatasource:# 主库数据源master:type: ${spring.datasource.type}driverClassName: org.h2.Driverurl: jdbc:h2:${spring.h2.file_path}${spring.h2.db_name}hikari:# 最大连接池数量maxPoolSize: 20# 最小空闲线程数量minIdle: 10# 配置获取连接等待超时的时间connectionTimeout: 30000# 校验超时时间validationTimeout: 5000# 空闲连接存活最大时间,默认10分钟idleTimeout: 600000# 此属性控制池中连接的最长生命周期,值0表示无限生命周期,默认30分钟maxLifetime: 1800000# 连接测试query(配置检测连接是否有效)connectionTestQuery: SELECT 1# 多久检查一次连接的活性keepaliveTime: 30000

初始化脚本

为了确保数据库初始化的顺利进行,请将您预先准备好的SQL初始化脚本放置于项目的resource的db文件夹中。这样设置后,系统将能够在启动时正确地识别并执行这些脚本,从而完成数据库的初始化工作。
初始化脚本
为了使项目能够顺利执行数据库初始化脚本,我们需要一个专门的工具来处理这一任务。
为此,我们将创建两个新的配置类:ApplicationContextRegisterH2DataInitConfig
这两个类将负责整合和配置项目所需的环境,确保脚本能够被正确执行。
ApplicationContextRegister 将用于注册和管理应用上下文,而 H2DataInitConfig 将专注于初始化H2数据库的数据。

package com.ray.h2Config;import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Component;/*** 定义一个注册器策略类,方便后续加载资源文件* ApplicationContextAware是Spring框架提供的接口,也叫做spring上下文的增强器,在项目启动时执行,会被spring处理* 当一个bean实现了该接口,通过setApplicationContext方法可以直接获取spring容器中的所有bean*/
@Component
public class ApplicationContextRegister implements ApplicationContextAware {private ApplicationContext applicationContext = null;/*** Spring容器启动时,会回调setApplicationContext方法,并传入ApplicationContext对象,之后就可对该对象进行操作。(例如获取spring容器中的所有bean)*/@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {this.applicationContext = applicationContext;}/*** 提供一个方法,用于加载sql脚本文件* @param url sql文件位置*/public Resource getResource(String url) {return this.applicationContext.getResource(url);}
}
package com.ray.h2Config;import cn.hutool.core.collection.CollectionUtil;
import com.ruoyi.common.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.core.io.Resource;
import org.springframework.jdbc.datasource.init.ScriptUtils;
import org.springframework.stereotype.Service;import javax.annotation.PostConstruct;
import javax.sql.DataSource;
import java.io.File;
import java.util.Arrays;
import java.util.List;/*** 初始化h2数据库*/
@Slf4j
@Service
// DataSource创建完后才初始化此类
@AutoConfigureAfter(DataSource.class)
public class H2DataInitConfig {@Value("${spring.h2.file_path}")private String filePath;// 初始化sqlprivate static final String SCHEMA = "classpath:db/schema.sql";private static final List<String> INIT_DATA_LIST = Arrays.asList("classpath:db/data.sql",);@AutowiredDataSource dataSource;@AutowiredApplicationContextRegister applicationContextRegister;@PostConstructpublic void init() throws Exception {// 文件锁,防止重复初始化File f = new File(filePath + File.separator + "h2_init.lock");if (!f.exists()) {log.info(">>> 开始初始化h2数据");boolean newFile = f.createNewFile();if (newFile && StringUtils.isNotBlank(SCHEMA)) {// 加载资源文件Resource schemaSql = applicationContextRegister.getResource(SCHEMA);// 手动执行SQL语句ScriptUtils.executeSqlScript(dataSource.getConnection(), schemaSql);// 初始化数据if (CollectionUtil.isNotEmpty(INIT_DATA_LIST)) {for (String initData : INIT_DATA_LIST) {Resource initDataSql = applicationContextRegister.getResource(initData);ScriptUtils.executeSqlScript(dataSource.getConnection(), initDataSql);}}}log.info(">>> 结束初始化h2数据");}}
}

结果

初次启动项目并完成数据初始化。

2024-12-13 16:32:01 [main] INFO  c.r.h2Config.H2DataInitConfig- >>> 开始初始化h2数据... 省略sql2024-12-13 16:32:01 [main] INFO  c.r.h2Config.H2DataInitConfig- >>> 结束初始化h2数据

执行完成


http://www.ppmy.cn/news/1555969.html

相关文章

211-基于FMC的1路1.5G ADC 1路 2.5G DAC子卡

一、板卡概述 FMC-1AD-1DA-1SYNC是我司自主研发的一款1路1G AD采集、1路2.5G DA回放的FMC、1路AD同步信号子卡。板卡采用标准FMC子卡架构&#xff0c;可方便地与其他FMC板卡实现高速互联&#xff0c;可广泛用于高频模拟信号采集等领域。 二、功能介绍 2.1 原理框图 2.2 硬件…

Java全栈项目 - 校园智慧节能管理平台

项目简介 校园智慧节能管理平台是一个基于Java全栈技术开发的现代化校园能源管理系统。该平台旨在通过智能化手段实现校园能源的精细化管理,提高能源使用效率,降低能源浪费,助力校园绿色可持续发展。 技术架构 后端技术栈 Spring Boot 2.xSpring SecurityMyBatis PlusMySQL…

大模型呼出机器人能够解决哪些问题?

大模型呼出机器人能够解决哪些问题&#xff1f; 原作者&#xff1a;开源呼叫中心FreeIPCC&#xff0c;其Github&#xff1a;https://github.com/lihaiya/freeipcc 大模型呼出机器人作为现代科技在客户服务领域的创新应用&#xff0c;能够解决多个方面的问题&#xff0c;以下是…

【Linux金典面试题(上)】41道Linux金典面试问题+详细解答,包含基本操作、系统维护、网络配置、脚本编程等问题。

大家好&#xff0c;我是摇光~&#xff0c;用大白话讲解所有你难懂的知识点 之前写了一篇关于 python 的面试题&#xff0c;感觉大家都很需要&#xff0c;所以打算出一个面试专栏。 【数据分析岗】Python金典面试题 这个专栏主要针对面试大数据岗位、数据分析岗位、数据运维等…

【深度学习】热力图绘制

热力图&#xff08;Heatmap&#xff09;是一种数据可视化方法&#xff0c;通过颜色来表示数据矩阵中的数值大小&#xff0c;以便更直观地展示数据的分布和模式。热力图在许多领域中都有应用&#xff0c;尤其在统计分析、机器学习、数据挖掘等领域&#xff0c;能够帮助我们快速识…

旅游系统旅游小程序PHP+Uniapp

旅游门票预订系统&#xff0c;支持景点门票、导游产品便捷预订、美食打卡、景点分享、旅游笔记分享等综合系统 更新日志 V1.3.0 1、修复富文本标签 2、新增景点入驻【高级版本】3、新增门票核销【高级版】4、新增门票端口【高级版】

题海拾贝:力扣 20、有效的括号

Hello大家好&#xff01;很高兴我们又见面啦&#xff01;给生活添点passion,开始今天的编程之路&#xff01; 我的博客&#xff1a;<但凡.-CSDN博客 我的专栏&#xff1a;《编程之路》、《题海拾贝》、《数据结构与算法之美》 欢迎点赞、关注&#xff01; 1、题目 2、题解 这…

分布式锁【Redis场景分布式锁篇】

文章目录 1.Redis分布式锁2.分布式锁其它方案1.主动轮询型1.MySQL分布式锁2.Redis分布式锁 2.监听回调型1.Etcd2.Zookeeper 总结 1.Redis分布式锁 锁通常用来控制共享资源&#xff0c;比如一个进程内有多个线程竞争一个数据的使用权限&#xff0c;解决方式之一就是加锁。分布式…