H2->Mysql数据迁移
需求背景
最近有一需求,原本项目中由于某些原因使用嵌入式数据库H2,鉴于嵌入式数据库可靠性以及不方便管理等因素,需要将数据库迁移到Mysql。
环境说明
SpringBoot:3.0.2
JDK:17
H2:2.1.214
spring-boot-starter-data-jpa:3.0.2
Mysql:8.0.32
实现过程
配置调整
原配置
pom.xml
xml
<!-- 省略其他依赖... -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>2.1.214</version>
<scope>runtime</scope>
</dependency>
dev.yml
yaml
spring:
datasource:
url: jdbc:h2:file:./data/cloak-ab
driver-class-name: org.h2.Driver
username: root
password: root789456
jpa:
database: h2
hibernate:
ddl-auto: update
show-sql: true
h2:
console:
path: /h2-console
enabled: true
settings:
web-allow-others: true
trace: true
修改配置
修改后pom.xml
xml
<!-- 省略其他依赖... -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.32</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>2.1.214</version>
<scope>runtime</scope>
</dependency>
修改后dev.yml
yaml
spring:
datasource:
url: jdbc:mysql://192.168.0.80:3306/cloak_ab?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=GMT%2B8&allowMultiQueries=true
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: root789456
jpa:
# 此处有修改
database: mysql
hibernate:
ddl-auto: update
show-sql: true
h2:
console:
path: /h2-console
enabled: true
settings:
web-allow-others: true
trace: true
主要修改点有三处:
①添加Mysql连接依赖
②数据库的连接地址和数据库驱动
③jpa使用的数据库
代码调整
新增DatasourceConfig配置类
配置Mysql主数据源,H2次数据源
DatasourceConfig.java
java
import lombok.Data;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.core.JdbcTemplate;
import javax.sql.DataSource;
@Configuration
public class DatasourceConfig {
@Data
@Configuration
@ConfigurationProperties(prefix="spring.datasource")
public static class MasterDatasourceProperties {
private String url;
private String driverClassName;
private String username;
private String password;
}
@Bean
@Primary
public DataSource dataSource(MasterDatasourceProperties masterDatasourceProperties) {
return DataSourceBuilder.create()
.driverClassName(masterDatasourceProperties.getDriverClassName())
.url(masterDatasourceProperties.getUrl())
.username(masterDatasourceProperties.getUsername())
.password(masterDatasourceProperties.getPassword())
.build();
}
@Primary
@Bean(name = "jdbcTemplate")
public JdbcTemplate jdbcTemplate(@Qualifier("dataSource") DataSource dataSource) {
return new JdbcTemplate(dataSource);
}
@Bean(name = "secondaryDataSource")
@Qualifier("secondaryDataSource")
public DataSource secondaryDataSource() {
return DataSourceBuilder.create()
.url("jdbc:h2:file:./data/cloak-ab")
.driverClassName("org.h2.Driver")
.username("root")
.password("root789456")
.build();
}
@Bean(name = "secondaryJdbcTemplate")
public JdbcTemplate secondaryJdbcTemplate(@Qualifier("secondaryDataSource") DataSource secondaryDataSource) {
return new JdbcTemplate(secondaryDataSource);
}
}
Mysql主数据源添加@Primary注解,jpa使用的默认是主数据源,如此一来jpa操作的就是Mysql数据库了。
使用secondaryJdbcTemplate
java
@Autowired
private AppParamDao appParamDao;
@Autowired
@Qualifier("secondaryJdbcTemplate")
protected JdbcTemplate secondaryJdbcTemplate;
@Override
public void h2ToMysql() {
String sql = "select * from app_param";
List<AppParam> appParams = secondaryJdbcTemplate.query(sql, new BeanPropertyRowMapper<>(AppParam.class));
appParamDao.saveAllAndFlush(appParams);
}
此时secondaryJdbcTemplate操作的就是H2数据库,而appParamDao操作的就是Mysql数据库
AppParamDao.java
java
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
import java.util.List;
import java.util.Optional;
import java.util.Set;
@Repository
public interface AppParamDao extends CrudRepository<AppParam, Long>, JpaRepository<AppParam, Long> {
}