【问题标题】:Creating tables on demand with Spring Boot Data JPA使用 Spring Boot Data JPA 按需创建表
【发布时间】:2020-01-28 22:50:53
【问题描述】:

我正在尝试创建一个 Spring Boot 应用程序,我想在其中按需创建和使用数据库表,而不为它们定义实体/存储库。

我有一个基础业务实体和业务类型实体来保留业务类型。我希望能够用自己的表为业务类型(比如 Coffeeshop)动态创建一个表(同时我可以将表的名称保留在 BusinessType 表上并决定从那里查询哪个表)。

因此,如果不定义实体和/或为 Coffeeshop 创建 CrudRepository,我可以创建一个名为 Coffeeshop 的表,然后再对其进行一些查询吗?

如果没有,我有什么选择?在典型的 Spring Data JPA 应用程序中,您如何处理具有基类型并允许系统具有更多具体类型(持久并与基类型关联)的情况?

谢谢

【问题讨论】:

  • 您可以使用模型创建表。创建一个具有@Entity 注释和@Table(name="yourtablename") 的类。也在您的 application.propertirs 文件中。设置 spring.jpa.hibernate.ddl-auto=create
  • 这是在编译之前定义实体的标准方法,我问的是我们是否可以在运行时创建数据库表并在以后使用它们。
  • 我也在寻找类似的解决方案。任何指针寻求帮助??
  • 寻找同样的问题 谁能帮忙?
  • 我想说动态创建表对于关系数据库来说是一种不好的方法,但是您可能想检查是否可以序列化为 Json?也许创建一个包含两列的表 - TYPE 和 PAYLOAD 并在 TYPE 列中写入“Coffeeshop”,并在 PAYLOAD 列中写入序列化 JSON 咖啡店。

标签: java spring-boot spring-data-jpa ddl generic-programming


【解决方案1】:

您描述的持久性策略不适合 JPA。 JPA 是一种 ORM(对象关系映射)策略,其中框架将数据从基于类的对象映射到模式定义的关系表中的行。如果表没有对应的类,或者类没有特定的表,这会使注释驱动的实现变得复杂。

要使用 JPA 解决您的问题,一个惯用的解决方案是将您的所有业务保存在一个表中(映射到业务实体类,如您所描述的),并在表上有一个(外)键以允许每个行有一个业务类型。然后,您可以通过查询(而不是针对不同的表)选择具有特定类型的业务集。

Business
id | type       | name           | etc...
1    COFFEESHOP   Alices Coffee

BusinessType
id          | name | industry
COFFEESHOP    Cafe   HOSPITAILITY

然后要获取系统中的所有咖啡店,您将定义一个 BusinessRepository 方法

@Query(value = "{ 'type': ?0  }")
List<Business> findAllByType(String type);

要使用您描述的表创建策略解决您的问题,您必须自己编写大部分数据访问层。您可以在手写的 BusinessDAO 类中执行此操作(不使用 JPA 或注释),该类将具有使用普通 JDBC 构造和执行 SQL 语句的方法,以实现所需的模式操作。如果您想要一个库来模拟 JPA 为您提供的 SQL 方言独立性,您可以查看 JOOQ。这种策略将需要更多的工作,并且这样的应用程序将需要模式编辑权限。在通常不鼓励使用的企业环境中。

【讨论】:

    【解决方案2】:

    几年前我曾经从事过这样一个项目——我们曾经使用过spring boot,但并没有故意使用hibernate/jpa/spring数据。

    恕我直言,JPA 的整个想法是提供实体(假设您是一个 Java 程序员,不一定了解 SQL / Db Schema)并让 hibernate/jpa 发挥它的魔力并定义模式给你(给定属性)。也可以“另辟蹊径”,让您的表已经存在并尝试创建实体,以便它们“映射”到 RDBMS 中的现有结构。

    您所描述的内容根本不适合这种方法。 所以在我们的项目中,由于我们不想处理 hibernate 引入的查询的复杂性,并希望有选择地使用您描述的动态结构,所以我们做了以下工作:

    • 使用Flyway 生成模式。该工具与 Spring boot 集成,因此当应用程序启动并检查模式版本时,它会被调用,如果它有更多“最新”脚本 - 它将更改应用到数据库 - 这就是所谓的“迁移”。另一个流行的替代方案是 liquidbase,它们都可以与 spring boot AFAIK 一起使用。
    • 我们使用JOOQ 来避免编写普通的JDBC 查询。如果您决定使用 JOOQ(我完全可以推荐这个工具 - 它对我们来说非常有用,简单、方便、类型安全),您可以阅读 this tutorial 以与 Spring Boot 集成。其他选择是MyBatis,或者如果你想去“低级”,使用JDBI或者可能是Spring的JdbcTemplate。我敢肯定还有其他选择。

    因此,基本上使用此设置,流程如下所示: 在构建时,您会生成位于表后面的 Java 代码 (JOOQ)。这段代码与 Hibernate 实体完全不同,它包含的信息刚好够用类似 JAVA DSL 的语言准备查询,它本身不会生成查询。

    当应用程序启动时 - 它会检查架构并应用迁移(flyway)。迁移是您在其中编写 SQL 的源文件。

    现在一个可能的警告是,您需要 RDBMS 级别的权限才能实际创建这样的表。因此,根据您的组织,这可能并非易事,因此我建议先与您的 DBA 讨论这种方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-05-21
      • 2018-05-22
      • 2019-12-02
      • 2018-01-17
      • 1970-01-01
      • 2018-05-11
      • 2016-10-11
      相关资源
      最近更新 更多