flyway 迁移 SQL 脚本中的相对路径

问题描述 投票:0回答:1

我想通过 Flyway 迁移将数据加载到列中

update PUBLIC.user set image=FILE_READ('./../../assets/images/testuser.png') where username='testuser';

但是我得到了

FileNotFoundException
。如果我使用完整路径,它可以工作,但我想在这里使用相对路径,因为它在每个系统上可能有所不同。使用的路径是相对于执行的迁移文件的路径。

这是资源文件夹内的目录结构:

├───db
    ├───assets
    │   └───images
    ├───fixtures
    ├───migration
    └───special
        ├───h2
        └───postgresql

迁移脚本位于

db/special/h2
内,图像位于
db/assets/images
内。

飞行路线:

  flyway:
    locations: "db/migration,/db/special/{vendor}"

如何妥善解决这个问题?

spring-boot flyway
1个回答
0
投票

我最终完成了以下

BaseJavaMigration
课程。

package db.migration;

import java.io.InputStream;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.io.IOUtils;
import org.flywaydb.core.api.migration.BaseJavaMigration;
import org.flywaydb.core.api.migration.Context;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.support.AbstractLobCreatingPreparedStatementCallback;
import org.springframework.jdbc.datasource.SingleConnectionDataSource;
import org.springframework.jdbc.support.lob.DefaultLobHandler;
import org.springframework.jdbc.support.lob.LobCreator;
import org.springframework.jdbc.support.lob.LobHandler;

public class V1_2_3__ImageLoader extends BaseJavaMigration {

    private static final Map<String, String> IMAGE_MAP = new HashMap<>();

    private static final Logger LOGGER = LoggerFactory.getLogger(V1_2_3__ImageLoader.class);

    /**
     * Default constructor.
     */
    public V1_2_3__ImageLoader() {
        IMAGE_MAP.put("testadmin", "testadmin.png");
        IMAGE_MAP.put("testmanager", "testmanager.png");
        IMAGE_MAP.put("testuser", "testuser.png");
    }

    @Override
    public void migrate(Context context) throws Exception {
        final JdbcTemplate jdbcTemplate =
                new JdbcTemplate(new SingleConnectionDataSource(context.getConnection(), true));
        int counter = 0;
        for (Map.Entry<String, String> entry : IMAGE_MAP.entrySet()) {
            ClassLoader cl = this.getClass().getClassLoader();
            InputStream inputStream = cl.getResourceAsStream("db/assets/images/" + entry.getValue());

            if (inputStream == null) {
                LOGGER.info("Could not find file {}.", entry.getValue());
                continue;
            }
            byte[] imageData = IOUtils.toByteArray(inputStream);

            // insert binary data to database
            String sqlQuery = "update PUBLIC.sd_user set image=? where username=?";
            LobHandler lobHandler = new DefaultLobHandler();
            Integer result =
                    jdbcTemplate.execute(sqlQuery, new AbstractLobCreatingPreparedStatementCallback(lobHandler) {
                        protected void setValues(PreparedStatement ps, LobCreator lobCreator) throws SQLException {
                            ps.setString(2, entry.getKey());
                            lobCreator.setBlobAsBytes(ps, 1, imageData);
                        }
                    });

            if (result != null) {
                counter = counter + result;
            }
        }
        LOGGER.info("Updated {} user images.", counter);
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.