我知道这来得太晚了,但对于未来遇到同样问题的访问者来说,这可能会有所帮助。
在我看来,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();
...
}
说明:类 (VX_yourflywaymigrationscript) 不受 CDI 容器管理,因此无法注入 DAO。 BeanProvider 正是为此而生的 - 它可以加载 Bean 并为您提供参考,即使您不在 CDI 上下文中。
希望对你有帮助。