【问题标题】:How to create a view or table from an Entity?如何从实体创建视图或表?
【发布时间】:2022-11-29 14:39:02
【问题描述】:

我对 SpringBoot 中 jpa 实体上下文中的视图有疑问。到目前为止,我正在使用自动创建功能,该功能通过 Java 中实体的定义自动创建表。现在我的应用程序已经发展到我需要使用视图的程度。我不想为所有表/实体编写和维护 sql create 语句,否则我可以简单地将 create view 语句添加到我不想使用的 schema.sql 文件中。相反,我有一个 commandLineRunner,它在启动后创建视图,但是在测试应用程序时它失败了,因为实体在创建个人视图之前引用了视图。

那么有没有一种方法可以在实体中编写一条sql create语句,可能带有注释以在实体实例化期间创建视图?

【问题讨论】:

  • 有一种方法可以引导 JPA。澄清一下,您想在启动期间创建实体和视图吗?
  • 是的,一切都应该在启动时创建。

标签: java sql spring-boot jpa entity


【解决方案1】:

在启动时,您可以初始化数据引导程序。我 got the code from here,它基本上是一个 void 方法,你的存储库 Autowired 可以在 Spring 启动时创建和加载你的数据。

我已经在自己的代码中实现了这个数据加载器,您可以在my public GitHub 上找到它。

通过使用抽象类,您可以扩展方法(将 dev 与 prod 类加载器分开),并使用 IoC 设置存储库并加载数据。我将 CRUD 与 Redis 一起使用,但它非常通用。

    private final PriceRepository priceRepository;

    @Autowired
    public ProductionDataLoader(PriceRepository priceRepository, KeywordRepository keywordRepository, AccountRepository accountRepository) {
        this.priceRepository = priceRepository;
    }

    @Override
    public void loadEnvironmentSpecificData() {
        doSomethingWithData();
    }

例如,通过使用 @Profile 注释,您可以将 devprod 分开。 这是我的一个爱好项目,我绝不是(认证)开发人员......

【讨论】:

  • 谢谢您的回答。不幸的是,我不是在寻找插入数据的方法,而是在实体通常创建表时创建视图。
【解决方案2】:

我找到了一种非常简单的方法,即如何创建一个视图而不必自动创建由 JPA 管理的所有表以及实体实例化。

基本上我让 spring boot 启动并创建所有表。这包括创建一个与 JPA 实体所需视图同名的表。 启动后,我只需删除表,然后在 sql 脚本中创建自己的视图。

它工作得很好,实体在表被删除后继续使用视图,因为它们都有相同的名称。

这是一些代码:

public class StartUpRunner implements CommandLineRunner {

   public static final String VIEW_INIT_FILE = "after_hibernate_init.sql";
   @Autowired
   private DataSource dataSource;

   @Override
   public void run(String... arg) throws Exception {
      createSQLViews();
   }

   private void createSQLViews(){
      boolean IGNORE_FAILED_DROPS = true;
      ResourceDatabasePopulator resourceDatabasePopulator = new ResourceDatabasePopulator(false, IGNORE_FAILED_DROPS , "UTF-8", new ClassPathResource(VIEW_INIT_FILE));
      resourceDatabasePopulator.execute(dataSource);
   }
}

在sql文件中应该有这样的东西:

DROP TABLE IF exists YOUR_VIEW_NAME;

CREATE OR REPLACE View YOUR_VIEW_NAME
//Your view creation statement here....

将标志“ignore failed drops”设置为 true 非常重要,因为在第一次启动后,视图将已经存在并且 sql 脚本在 drop tables 语句上失败,这将关闭应用程序。这样SpringBoot会忽略失败的语句,正常启动。

这种方法的缺点是您不能再使用 @DataJpaTest 测试视图,因为 StartUpRunner 需要创建视图。至少如果你像我一样使用 SpringBoot 的嵌入式 H2 数据库,它需要在每个测试类之前进行初始化。

我用于测试视图的测试注释如下所示:

@ActiveProfiles("sqltest")
@ExtendWith(SpringExtension.class)
@SpringBootTest
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)

我正在使用 testMethodOrder 因为 sql 插入的数据在每次测试后不再被清除,我只在第一次测试之前插入数据并在所有测试中使用它。

activeProfiles 注释应该是相对不言自明的。我在那里指定测试 H2 数据库和其他应用程序特定设置。

关于如何将视图压缩到 JPA 的自动创建功能中,请随时询问有关此方法的更多信息。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-24
    • 1970-01-01
    • 2013-11-30
    • 1970-01-01
    相关资源
    最近更新 更多