在遗留系统的数据库表,我们有编号列像C1,C2,C3,C100或M1,M2,M3,M100。
这个列表示BLOB数据。

这是不可能改变任何它这个数据库。

通过访问用户使用嵌入我们的地图的所有列为单一的领域。然后在嵌入我们复盖的名字,通过使用100替代注释。

最近,我们已经交换以休眠和我已经找到的东西喜欢 UserCollectionTypeCompositeUserType.但我没有发现任何使用的情况下,靠近我的。

是否有可能实现某些用户类型,通过使用休眠于能够在地图上的捆绑列的一个集合 没有其他查询?

编辑:
正如你可能注意到的列的名称可能不同于表表。我想要创造一种类型,如"LegacyArray"没有必要指定的所有@列每一次我使用这种类型。但相反我会用

  @Type(type = "LegacyArrayUserType",
        parameters =
   {
      @Parameter(name = "prefix", value = "A"),
      @Parameter(name = "size", value = "128")
   })
   List<Integer> legacyA;

  @Type(type = "LegacyArrayUserType",
        parameters =
   {
      @Parameter(name = "prefix", value = "B"),
      @Parameter(name = "size", value = "64")
   })
   List<Integer> legacyB;
有帮助吗?

解决方案

我可以想到的几种方式,我会这样做。

1.创意见收集的信息,模拟标准化表格的结构,地图,它休眠作为一个集合:

假设现有的表格被称为 primaryentity, 我会创造一个看法,即类似于以下内容:

-- untested SQL...
create view childentity as
(select primaryentity_id, c1 from primaryentity union
select primaryentity_id, c2 from primaryentity union
select primaryentity_id, c3 from primaryentity union
--...
select primaryentity_id, c100 from primaryentity)

现在从休眠状态的角度来看, childentity 只是一个规范化表,有一个外国的关键 primarykey.映这应该是相当直截了当,而是涵盖在这里:

这种方法的好处:

  • 从休眠的观点,表正常化,这是一个相当简单的映射
  • 没有更新现有表格

在缺点:

  • 数据是只读的,我不认为你看来可以被限定在一个可更新的方式(我可能是错的)
  • 需要改变数据库,可能需要创造大量的意见

或者,如果你DBA甚至不会让你加入一个数据库,或者如果需要执行更新:


2.使用休眠的 动态模型映射设施 到地图你C1,C2,C3性 地图, 和有些代码你 层做适当的对话之间的地图和收集的财产:

我从来没有做过这个了我自己,但我相信休眠不能让你在图表中以散.我不知道该如何动态休眠可以让你做到这一点(即,你可以逃脱,只需指定的表格的名称,并具有休眠自动地图的所有列?), 但这是另一种方式我可以认为,这样做。

如果说这种做法虽然,一定要使用的 数据访问的对象 模式,并确保内部执行情况(使用的散)是隐藏的从客户代码。也一定要检查之前编写的数据库的尺寸您的收藏不超过可用的数量列。

这种方法的好处:

  • 没有改变该数据库在所有
  • 数据更新
  • O/R映较简单

在缺点:

  • 许多管道的道层地图的适当类型
  • 使用休眠实验的特点,可以改变未来

其他提示

就个人而言,我认为设计听起来就像它打破第一范式关系数据库。如果你需要C101或M101,会发生什么?再次更改您的架构?我认为这是非常侵入。

如果您添加休眠进来,它甚至更糟。添加C101或M101意味着必须改变你的Java对象,你的Hibernate映射,应有尽有。

如果你有1:用C和M表m关系,你能处理我只是通过增加额外的行举的案例。 Java对象包含集合或收藏。你的Hibernate映射是一个一对多不会改变。

也许你看不到任何Hibernate的例子,因为它是不建议设计符合你的情况的原因。

如果你一定要,也许你应该看看休眠组件映射

更新:事实上,这是传统的被适当的注意。我培养第一范式的一点是尽可能多为别人,因为它是谁贴的问题,谁的人可能会发现在未来的这个问题。我不想回答这个问题以这样一种方式,它静静地声称这种设计为“好”。

他指出休眠组件映射是中肯,因为知道你在找什么,可当你要搜索的按键名称。休眠允许一个对象模型比其映射关系模型更细粒度。你可以自由的非规范化架构模型(例如,姓名和地址的对象作为一个更大的Person对象的一部分)。这只是他们给这种技术的名称。这可能有助于找到其他的例子还有。

很抱歉,如果我在这里误解你的问题,我不知道很多关于Hibernate。但不能从数据库中选择时正好连接得到的东西像你想要什么?

像:

SELECT whatever
     , C1||C2||C3||C4||...||C100 AS CDATA
     , M1||M2||M3||M4||...||M100 AS MDATA
FROM ...
WHERE ...

(当然,连接运算符的RDBMS之间是不同的。)

[编辑],我建议使用CompositeUserType下面是一个例子。另外还有228F页上的一个很好的例子在书中的“Java持久化使用Hibernate。”

这允许您处理的许多列作为Java中的单个对象。

的映射如下所示:

@org.hibernate.annotations.Columns(columns = {
    @Column(name="C1"),
    @Column(name="C2"),
    @Column(name="C3"),
    ...
})
private List<Integer> c;

Hibernate将加载在一旦所有列中的正常查询期间。

在你的情况,你必须从列表中复制int类型为固定数量的nullSafeSet列。伪代码:

for (int i=1; i<numColumns; i++)
    if (i < list.size())
        resultSet.setInt(index+i, list.get(i));
    else
        resultSet.setNull(index+i, Hibernate.INTEGER.sqlType());

nullSafeGet必须创建列表,并停止添加元素时的列是NULL。对于额外的安全性,我建议创建自己的列表实现不允许增长超过列数(继承ArrayList和覆盖ensureCapacity())。

[EDIT2]如果你不想输入所有@Column注释,使用代码生成他们。这可能是因为你给一个名称和一些脚本那样简单,它打印@Column(...)到System.out。脚本运行后,刚切&的数据粘贴到源。

其他唯一的解决办法是将访问内部休眠API构建在运行时的信息,但该API是内部的,所以很多东西是私人的。您可以使用Java反射和setAccessible(true)但代码可能将无法生存休眠的下一次更新。

您可以使用UserTypes的列给定数目映射到任何你想要的类型。这可能是一个集合,如果(例如)对于集合总是在大小用公知的若干项目的界定。

这是一段时间(> 3年),因为我用的Hibernate所以我很生疏,但我记得它是很容易做到的;您的BespokeUserType类被传递的ResultSet水合物你的对象从它

我也从来没有使用休眠。

我建议在一种解释语言编写的一个小程序(例如的Python ),可以在其中执行字符串就好像它是一个命令。你可以构建出需要的繁琐工作出去做你想要做手工什么的声明。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top