java 的飞行路线迁移

Flyway Migration with java

我了解到使用 java 的 flywaydb 迁移可与 JDBC 连接一起使用,并且还通过 SpringTemplate spring 支持,但 flyway 不适用于 DAO。

对于 tables/entities 有更多关系的人来说,使用 DAO 进行迁移比 sql 更容易。

是否有解决此问题的解决方案或解决方法?

您的 DAO 依赖于 Flyway 旨在改变的结构。因此,我们这里有先有鸡还是先有蛋的问题。解决这个问题的方法是 运行 在您的应用程序的其余部分(包括 DAO)初始化之前使用 Flyway。

首先,Flyway有自己的交易管理系统,不使用Spring交易处理。

如果您的 DAO 扩展 JdbcDaoSupport,您可以手动实例化您的 DAO,然后在 DAO 中手动注入提供的 JdbcTemplate

public class MyJdbcMigration implements SpringJdbcMigration {
  public void migrate(JdbcTemplate jdbcTemplate) {
    MyJdbcDao dao = new MyJdbcDao();
    dao.setJdbcTemplate(jdbcTemplate);
    dao.updateDate();
  }
}

我知道这来得太晚了,但对于未来遇到同样问题的访问者来说,这可能会有所帮助。

在我看来,Flyway 的创建者在这个问题上实际上是错误的。只要您不在更新脚本中更改数据库结构,就可以使用业务逻辑迁移数据,并且不存在先有鸡还是先有蛋的问题。

一个例子:你的数据库中有一个字段“密码”,它是明文的。出于安全考虑,您现在想要使用特殊的散列函数并对数据库中的所有密码进行散列(它应该是安全的,并且数据库没有这样做的功能)。哈希函数在您的 UserDAO 中声明,并在创建用户或更改密码时调用。虽然这不是一个完美的例子,但在许多可能的场景中访问 DAO 进行迁移是有意义的。

幸运的是我的一个同事找到了解决问题的办法,只需要5行左右的代码。您还需要将 Apache Deltaspike 添加到您的依赖项中(如果尚未添加)。

在您的 DAO 中,为 BeanProvider 添加导入:

import org.apache.deltaspike.core.api.provider.BeanProvider;

然后我们简单地让DAO成为一个单例:

public static UserDao getInstance() {
    return BeanProvider.getContextualReference(UserDao.class, false, new DaoLiteral());
}

差不多就这些了。在您的 Flyway 脚本中,您现在可以访问 DAO:

@Override
public void migrate(Connection cnctn) throws Exception{
    UserDao userdao = UserDao.getInstance();
    List<User> userList = userdao.getAllUsers();
    ...
}

说明:Class (VX_yourflywaymigrationscript) 不受 CDI 容器管理,因此无法注入 DAO。 BeanProvider 正是为此而生——它可以加载 Bean 并为您提供参考,即使您不在 CDI 上下文中也是如此。

希望对您有所帮助。