具有一列或多列和结果映射的动态本机查询(对象与对象[])

时间:2018-09-24 10:48:22

标签: java jpa java-ee-7 jpa-2.1

我有一些非常基本的SQL,其中主要交换列和表,例如如此简单:

Select :COLUMNS from :TABLE

SQL可以具有1或许多列,并且始终有1个表。我之所以使用JPA,只是因为我们在Java EE 7服务器上。因此,运行本机查询的代码如下:

@PersistenceContext(unitName = "sample")
EntityManager entityManager;
public List<Result> getResults() {
  return Stream.of("SELECT one FROM demo1",
                   "SELECT two, columns FROM demo2")
               .map(entityManager::createNativeQuery)
               .map(Query::getSingleResult)
               .flatMap(result -> {
                  // is Object for the first...
                  // and Object[] for the second...
                  if (result instanceof Object[]) {
                    return Arrays.stream((Object[])result);
                  } else {
                    return Stream.of(result);
                  }
               })
               .map(Result::new)
               .collect(Collectors.toList());
}

我现在遇到的问题:如果仅使用一列,则直接得到Object,如果使用多列,则得到Object[]。是否有一些属性/设置可以始终获得Object[]?我看到setHint(ResultType, Array)可以解决该问题,但是它需要特定于实现的提示。

我首先想要一个Object[]的原因:(除了该特定instanceof上的代码已经很难看),结果本身只有在我仍然知道合适的列的情况下才有用。该代码示例简化了该示例,但是随着SQL的动态创建,这些列也是已知的,因此可以重用。如果还有其他可以用于这种构造的结果集映射,那么我会不知所措。

现在,我只使用显示的instanceof-检查,但是我想知道标准中是否有某些东西可以解决该问题。欢迎提供任何有关如何更好地解决该问题的提示(当然,无需进一步依赖)。

注意:我无法修改表格,这样的结果确实很有意义。

1 个答案:

答案 0 :(得分:0)

您可以跳过整个instanceof测试,并利用Stream.of()方法的多态签名来接受单个对象或对象数组:

static <T> Stream<T> of(T... values).
static <T> Stream<T> of(T t)

这将使您的代码更具可读性:

public List<Result> getResults() {
  return Stream.of("SELECT...", "SELECT...")
               .map(entityManager::createNativeQuery)
               .map(Query::getSingleResult)
               .flatMap(result -> Stream.of(result) )
               .map(Result::new)
               .collect(Collectors.toList());
}