我想通过 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}"
如何妥善解决这个问题?
我最终完成了以下
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);
}
}