数据库改变和Spring Boot JPA

时间:2016-02-02 14:54:12

标签: java spring jpa spring-boot spring-data-jpa

我希望在桌面应用程序更新后在嵌入式derby数据库上运行更改。为此,我尝试使用类似于此的alter query创建JPS存储库:

@Repository
public interface DatabaseUpdates {
    @Modifying
    @Query("alter table my_table add column my_column clob", nativeQuery = true)
    void alterMyTableAddMyColumn();
}

并在像这样的更新程序类中使用它

@Component
public class DatabaseUpdater {
    @Autowired
    private DatabaseUpdates databaseUpdates;

    private void alterMyTable() {
        // some logic that checks it the update needs to happen is here
        databaseUpdates.alterMyTableAddMyColumn();
    }
}

这会引发NoSuchBeanDefinitionException: No qualifying bean of type DatabaseUpdates例外。

我还尝试DatabaseUpdates扩展org.springframework.data.repository.Repository,但后来在使用什么作为域类型方面遇到了问题。

我正在使用spring-boot-starter-data-jpa 1.2.3.RELEASE。

编辑:这是为了支持旧应用,我正在寻找支持数据库更新的直接方法。数据库迁移工具很棒但不适合此修复。我一直希望这个项目已经使用一个月超过一个月了,并且很快就会将一个项目集成到下一个版本中。

4 个答案:

答案 0 :(得分:1)

这听起来像个糟糕的主意。有一些框架,专门为您的用例开发,并受Spring Boot支持,如FlywayLiquibase。然后,您可以在SQL或Java代码(对于Flyway)或XML,SQL,YAML或JSON文件(对于Liquibase)中指定更改。这些框架将检查哪些迁移是必要的,并且它们还跟踪执行迁移的时间。

答案 1 :(得分:1)

我不会把它放在Spring JPA中。如果你提到它是临时的,也许直接尝试一些JDBC并在数据库上运行查询。尝试记录您在表中所做的更改(类似于liquibase正在执行的操作),因此您不会多次运行查询。 也许在Spring构建DataSourceDatabaseConfiguration之前尝试运行它。

    @Configuration
    @EnableJpaRepositories("")
    @EnableTransactionManagement
    public class DatabaseConfiguration implements EnvironmentAware {

            @Bean(destroyMethod = "close")
            public DataSource dataSource(DataSourceProperties dataSourceProperties, ApplicationProperties applicationProperties)
                    throws SQLException {
                LOG.debug("Configuring Datasource");
                //some code
                alterSchema();
                return new HikariDataSource(config);
            }

            private void alterSchema() {
              // JDBC connection and queries to alter the schema
            }

    }

答案 2 :(得分:0)

虽然不是最佳实践,但您可以暂时使用本机JDBC,从现有DataSource获取连接。如果只添加列,请确保检查对象(列)是否已存在。

答案 3 :(得分:0)

您的存储库可以执行transaction并使用native query构建EntityManager,如以下代码所示

import org.springframework.stereotype.Repository;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.transaction.Transactional;

@Repository
public class DatabaseUpdates{

    @PersistenceContext
    private EntityManager entityManager;

    //ALTER TABLE `my_table` ADD COLUMN `my_column` VARCHAR(100) AFTER `after_column`;
    @Transactional
    public void alterMyTableAddMyColumn(String tableName, String columnName, 
        String columnType, String afterColumnName) {

        String query = "ALTER TABLE `" + tableName + "` ADD COLUMN `" + columnName + "` " +
            columnType + " AFTER `" + afterColumnName + "`";

        entityManager.createNativeQuery(query).executeUpdate();
    }
}

您的更新程序类这样调用您的存储库

import org.springframework.stereotype.Component;
import org.springframework.beans.factory.annotation.Autowired;

@Component
public class DatabaseUpdater {
    @Autowired
    private DatabaseUpdates databaseUpdates;

    private void alterMyTable() {
        // some logic that checks it the update needs to happen is here
        String tableName = "my_table";
        String columnName = "my_column";
        String columnType = "VARCHAR(100)";
        String afterColumnName = "after_column";

        databaseUpdates.alterMyTableAddMyColumn(tableName, columnName, 
            columnType, afterColumnName);
    }
}