首页 > 解决方案 > 具有一列或多列和结果映射的动态本机查询(Object vs Object[])

问题描述

我有一些非常基本的 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-check,但我想知道标准中是否有一些东西可能已经解决了这个问题。欢迎任何有关如何更好地解决该问题的提示(当然无需进一步依赖)。

注意:我无法调整表格,结果以这种方式真的很有意义。

标签: javajpajava-ee-7jpa-2.1

解决方案


您可以跳过整个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());
}

推荐阅读