首页 > 解决方案 > 将过滤后的第二个表的两列映射到一个 Collection 成员

问题描述

概括

我想知道是否可以将以下查询映射到实体类的成员Bar

Select f.columnA, f.columnB From Foo f Where f.barId = '[someDynamicBarId]';

注意:我无法更改架构(例如添加映射表)。

背景

我有课程BarFoo并且我想从一个非常大的表(10m个条目)中添加一个Map<String, BigDecimal>List<Object[]>到仅包含条目的条目。BarFooBar.barId = '[barId]'

我在延迟加载中显示50 个 元素,但我当前的获取和获取解决方案甚至对于这50个条目非常慢(80秒):BardataTablecolumnAcolumnBFoo

@OneToMany(fetch = FetchType.EAGER, mappedBy = "barId")
private List<Foo> fooList; // fooList.size() == 500

这应该替换为

private Map<String, BigDecimal> fooMap;

或者

private List<Object[]> fooList; // object { columnA, columnB }

我尝试@ElementCollection@OneToManyHibernate@Where@WhereJoinTable. 问题是我无法在这些查询中定义变量。@Formula也不起作用,因为它旨在仅返回一行。

结构

这些课程是:

class Bar {

   @Id
   private String barId;

   @OneToMany(fetch = FetchType.EAGER, mappedBy = "barId")
   private List<Foo> fooList;

   ...
}


class Foo {

   @Id
   private String fooId;

   private String columnA; // not unique

   private BigDecimal columnB; // not unique

   private String barId; // not unique

   ...
}

columnA每个人都是独一无二的barId

barId  columnA
---------------
 b01    cA01
 b01    cA02
 b01    cB01

 b02    cA01
 b02    cA02
 b02    cB01

结果

我想要Bar这样:

class Bar {

   @Id
   private String barId;

   @ElementCollection
   @MapKeyColumn(name = "columnA") // ?
   @Column(name = "columnB") // ?
   // ? @Filter('barId = :barId')
   // ? @Formula('Select f.columnA, f.columnB From Foo f Where f.barId = barId')
   // ? @Where('barId = :barId')
   private Map<String, BigDecimal> fooMap;

   ...
}

实际上,如果我能在合理的时间内得到 ( barId,)columnA的组合,我的问题就会得到解决。columnB不必像我上面描述的那样实现。这些表在数据库中请求的列上建立索引。

标签: javahibernatejpa

解决方案


Gna,我刚刚找到了解决方案。

class Bar {

  @Id
  private String barId;

  @ElementCollection(targetClass = BigDecimal.class, fetch = FetchType.EAGER )
  @JoinTable(name="Foo", joinColumns = @JoinColumn(name = "barId"))
  @MapKeyColumn(name = "columnA")
  @Column(name = "columnB")
  private Map<String, BigDecimal> fooMap;

  ...
}

主要问题仍然存在:它非常慢(57秒)。有什么提高速度的建议吗?

编辑:在数据库中重新创建索引解决了这个问题。现在只需不到一秒钟的时间即可获得完整的桌子。


推荐阅读