【问题标题】:Change table name in runtime with JPA使用 JPA 在运行时更改表名
【发布时间】:2018-03-21 21:17:35
【问题描述】:

我实现了一个使用数据库的服务。数据库中的表很少。在这些表中存储一些计算的结果。另一个服务为每个计算创建一个新表,现在表列表如下所示:

  • calculation_1_0
  • calculation_2_0
  • calculation_2_1
  • calculation_2_2
  • calculation_3_0
  • calculation_X_Y

所有表的表结构都相同。

是否可以使用 JPA 从这些表中获取数据而无需为每个表创建实体?

【问题讨论】:

  • 非常糟糕的表结构设计。应该只有一张表,其中包含我们记住计算编号的列“计算编号”,例如3_0、2_1等。重新设计模型,这是最好和最简单的解决方案。
  • @krokodilko 我完全同意你的观点,但我不负责改变设计结构,因为我不是它的开发者,我只是将它用于我的目标。

标签: java hibernate jpa


【解决方案1】:

在运行时创建表是个坏主意。鉴于您知道列是什么,更好的设计是拥有一个calculation_type 查找表并在您的计算表中创建一个外键并对其进行索引。然后,您可以预先创建实体并具有更好的关系完整性。

要直接回答这个问题,不能动态创建新表然后使用 JPA 映射。您可以使用纯 JDBC,但 JPA 不支持它是有原因的 - 这是糟糕的设计。

【讨论】:

    【解决方案2】:

    @krokodilko 我完全同意你的看法,但我不负责 改变设计结构,因为我不是它的开发者,我只是 用它来实现我的目标。

    如果你必须忍受它,那么我会动态地删除/创建一个视图或同义词来欺骗 JPA。这个想法是:

    • 在加载 EntityManager 之前,创建一个具有固定名称的视图/同义词,它将选定的表映射到该通用名称
    • 在 JPA 中,使用 XML 或注释将实体映射到此视图/同义词的通用名称
    • 加载实体管理器

    这种方法有缺点:

    • 只有应用程序的一个实例/线程可以同时使用此视图/同义词,这在多用户环境中不起作用(除非所有实例/线程同步并且同时关闭/打开实体管理器当视图更新/重新创建时 - 但我什至无法想象这样的解决方案,这将是一个包含许多陷阱和错误的巨大项目)
    • 一次只能使用一个表,要使用另一个表,必须关闭实体管理器,必须删除视图/同义词,然后重新创建,然后必须重新加载实体管理器

    您还可以创建一个合并多个表的视图,如下所示:

    CREATE VIEM my_common_name AS
    SELECT '1_0' as calc_name, t.* FROM calculation_1_0 t UNION ALL
    SELECT '2_0' as calc_name, t.* FROM calculation_2_0 t UNION ALL
    .....
    .....
    SELECT 'X_Y' as calc_name, t.* FROM calculation_X_Y t
    

    但同样 - 如果该进程创建了一个新表,您必须关闭实体管理器,使用新表名重新创建此视图,然后再次加载实体管理器。

    从性能的角度来看,这将是非常糟糕的——你不能在这个视图上创建任何索引,它不能被分区、调整或物化,每个针对这个怪物视图的查询几乎总是对所有这些表进行全表扫描。


    一开始就设计了一个糟糕的数据库结构,这就像设计带有不同充电插座的手机一样,每次为手机充电时都需要使用不同的插头。最好的办法是修复这个原始错误因为这样的修复很容易完成,只需创建一个带有额外列“calculation_name”的公用表并修复一个将数据保存到这些的代码表(将数据插入公用表而不是每次都创建新表),其他一切都将是解决这个问题的麻烦尝试。


    如果我是你,那么我会去找我的经理,我会告诉他,糟糕的设计存在这样的技术问题。我会告诉他我们现在可以修复它,而且会花费一点($)。我会告诉他,如果我们现在不修复它,那么这个功能的每一次更改都会越来越麻烦和昂贵($$, $$$, $$$$$ - 因为人工天数、维护成本,性能/硬件等),最终这样的修复根本不可能,我们将不得不从头开始重写这个系统(这将花费我们 $$$$$$)。
    经理视野更开阔,他应该知道商业计划,他应该知道这个功能将来会不会开发,或者半年就会被放弃。这是经理的决定 - 现在投资 $ 并在未来节省 $$$$$,或者什么也不做,因为它不会给我们未来带来任何利润。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-17
      相关资源
      最近更新 更多