如何用Liquibase从MySQL加载属性并结合Maven过滤器替换其他配置文件
实现Liquibase读取MySQL属性并用于Maven资源过滤替换
以下是基于你提供的基础POM,实现从MySQL加载属性并替换配置文件占位符的具体步骤:
1. 准备数据库属性表
假设你的MySQL数据库中存在存储配置属性的表,结构如下:
CREATE TABLE config_properties ( prop_key VARCHAR(255) PRIMARY KEY, prop_value VARCHAR(255) NOT NULL );
将需要的配置键值对插入该表,例如:
INSERT INTO config_properties (prop_key, prop_value) VALUES ('app.title', 'Sample Web App'), ('app.api.url', 'https://api.example.com/v1');
2. 修改Liquibase变更集,导出数据库属性
在src/main/resources/changelog-master.xml中添加变更集,执行SQL查询并将结果写入临时属性文件:
<changeSet id="export-db-properties" author="laxman"> <!-- 导出属性到临时文件(需MySQL用户具备文件写入权限) --> <sql> SELECT CONCAT(prop_key, '=', prop_value) INTO OUTFILE '/tmp/db-properties.tmp' FIELDS TERMINATED BY '\n' FROM config_properties; </sql> <!-- 复制到Maven构建目录 --> <copy file="/tmp/db-properties.tmp" toFile="${project.build.directory}/generated-resources/db-properties.properties"/> <!-- 清理临时文件 --> <delete file="/tmp/db-properties.tmp"/> </changeSet>
3. 调整Maven POM配置
3.1 提前Liquibase执行阶段
确保Liquibase在Maven资源过滤前完成属性文件生成,修改Liquibase插件的执行阶段:
<plugin> <groupId>org.liquibase</groupId> <artifactId>liquibase-maven-plugin</artifactId> <version>4.15.0</version> <configuration> <changeLogFile>src/main/resources/changelog-master.xml</changeLogFile> <propertyFile>src/main/resources/liquibase.properties</propertyFile> </configuration> <executions> <execution> <phase>generate-resources</phase> <!-- 提前到资源生成阶段,确保属性文件先就绪 --> <goals> <goal>update</goal> </goals> </execution> </executions> <dependencies> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.33</version> </dependency> </dependencies> </plugin>
3.2 配置Maven加载生成的属性文件
在<build>节点中添加过滤器配置,加载Liquibase生成的属性文件,并将生成目录纳入资源处理:
<build> <!-- 加载生成的数据库属性文件作为过滤源 --> <filters> <filter>${project.build.directory}/generated-resources/db-properties.properties</filter> </filters> <resources> <resource> <directory>src/main/resources</directory> <filtering>true</filtering> <includes> <include>**/*.xml</include> <include>**/*.properties</include> </includes> </resource> <!-- 纳入生成资源目录,避免文件丢失 --> <resource> <directory>${project.build.directory}/generated-resources</directory> <filtering>false</filtering> </resource> </resources> <!-- 保留原有的其他插件配置 --> </build>
4. 在目标配置文件中使用占位符
例如在src/main/resources/app.properties中,使用与数据库prop_key对应的占位符:
# 占位符将被数据库中的值替换 app.name=${app.title} app.backend.url=${app.api.url}
5. 验证执行
运行Maven命令触发资源处理:
mvn clean process-resources
查看target/classes/app.properties,占位符应已被数据库中的实际值替换。
无MySQL文件写入权限的替代方案
如果你的MySQL用户没有文件写入权限,可通过Java代码读取数据库并生成属性文件:
- 编写属性导出类
DbPropertiesExporter.java(放在src/main/java/com/laxman/sample/):
import java.io.FileWriter; import java.io.IOException; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.Statement; import java.util.Properties; public class DbPropertiesExporter { public static void main(String[] args) { Properties dbProps = new Properties(); try { dbProps.load(DbPropertiesExporter.class.getClassLoader().getResourceAsStream("liquibase.properties")); String url = dbProps.getProperty("url"); String username = dbProps.getProperty("username"); String password = dbProps.getProperty("password"); try (Connection conn = DriverManager.getConnection(url, username, password); Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery("SELECT prop_key, prop_value FROM config_properties"); FileWriter writer = new FileWriter(args[0])) { while (rs.next()) { writer.write(rs.getString("prop_key") + "=" + rs.getString("prop_value") + "\n"); } } } catch (Exception e) { e.printStackTrace(); System.exit(1); } } }
- 在POM中添加exec插件执行该类:
<plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>exec-maven-plugin</artifactId> <version>3.1.0</version> <executions> <execution> <phase>generate-resources</phase> <goals> <goal>java</goal> </goals> <configuration> <mainClass>com.laxman.sample.DbPropertiesExporter</mainClass> <arguments> <argument>${project.build.directory}/generated-resources/db-properties.properties</argument> </arguments> </configuration> </execution> </executions> </plugin>
内容的提问来源于stack exchange,提问作者Laxman Edara
相关产品推荐
相关产品推荐

