如何利用Spring Flyway占位符列表在SQL脚本中循环插入数据?
Flyway占位符实现列表循环插入的方案
Flyway原生的spring.flyway.placeholders并不支持直接传入列表并在SQL脚本中执行循环逻辑——它的占位符仅做简单的字符串替换,没有内置的循环语法。不过你可以通过以下几种方式实现需求:
方案一:配置层拼接SQL兼容格式
把字符串列表直接拼接成SQL插入语句支持的批量值格式,再通过占位符传入脚本:
- 在配置文件中设置:
spring.flyway.placeholders.values="'first', 'second', 'third'" - 在SQL迁移脚本中直接使用占位符:
这种方式本质是把列表转成了SQL能识别的批量值,适合简单的批量插入场景。INSERT INTO your_table (target_column) VALUES (${values});
方案二:自定义Flyway回调类
通过Java代码实现批量插入逻辑,注册为Flyway的回调,在迁移过程中执行:
- 编写回调类:
import org.flywaydb.core.api.callback.Callback; import org.flywaydb.core.api.callback.Context; import org.flywaydb.core.api.callback.Event; import javax.sql.DataSource; import java.sql.Connection; import java.sql.PreparedStatement; import java.util.List; public class BatchInsertCallback implements Callback { private final List<String> dataList = List.of("first", "second", "third"); @Override public boolean supports(Event event, Context context) { // 指定在迁移开始前执行 return event == Event.BEFORE_MIGRATE; } @Override public void handle(Event event, Context context) { try (Connection conn = context.getDataSource().getConnection()) { String insertSql = "INSERT INTO your_table (target_column) VALUES (?)"; try (PreparedStatement stmt = conn.prepareStatement(insertSql)) { for (String value : dataList) { stmt.setString(1, value); stmt.addBatch(); } stmt.executeBatch(); } } catch (Exception e) { throw new RuntimeException("批量插入数据失败", e); } } @Override public String getCallbackName() { return "BatchInsertCallback"; } @Override public boolean canHandleInTransaction(Event event, Context context) { return true; } } - 在Spring Boot配置中注册回调:
这种方式灵活性最高,适合复杂的业务逻辑场景。spring.flyway.callbacks=com.your.package.BatchInsertCallback
方案三:构建阶段动态生成SQL脚本
借助Maven/Gradle的资源插件,结合模板引擎动态生成包含所有插入语句的SQL脚本:
比如用Maven的maven-resources-plugin配合Velocity模板:
- 创建Velocity模板文件(
src/main/resources/templates/insert-data.vm):#foreach($item in $dataList) INSERT INTO your_table (target_column) VALUES ('$item'); #end - 在pom.xml中配置插件,传入列表参数并生成最终SQL脚本:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-resources-plugin</artifactId> <version>3.3.1</version> <executions> <execution> <id>generate-sql-script</id> <phase>generate-resources</phase> <goals> <goal>copy-resources</goal> </goals> <configuration> <outputDirectory>${project.build.directory}/generated-resources/flyway</outputDirectory> <resources> <resource> <directory>src/main/resources/templates</directory> <filtering>true</filtering> <includes> <include>insert-data.vm</include> </includes> </resource> </resources> <properties> <dataList>first,second,third</dataList> </properties> </configuration> </execution> </executions> <dependencies> <dependency> <groupId>org.apache.velocity</groupId> <artifactId>velocity</artifactId> <version>1.7</version> </dependency> </dependencies> </plugin> - 配置Flyway扫描生成的脚本目录:
spring.flyway.locations=classpath:db/migration,file:target/generated-resources/flyway
内容的提问来源于stack exchange,提问作者maria_so
相关产品推荐
相关产品推荐

