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 上下文中也是如此。
希望对您有所帮助。
我了解到使用 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 上下文中也是如此。
希望对您有所帮助。