diff --git a/src/main/java/io/ebean/SqlQuery.java b/src/main/java/io/ebean/SqlQuery.java index 1e6ec1edf..8f8b9ed01 100644 --- a/src/main/java/io/ebean/SqlQuery.java +++ b/src/main/java/io/ebean/SqlQuery.java @@ -93,13 +93,42 @@ public interface SqlQuery extends Serializable { * .setParameter(1, 2) * .findSingleAttribute(BigDecimal.class); * - * * } * + *

+ * The attributeType can be any scalar type that Ebean supports (includes javax time types, Joda types etc). + *

+ * * @param attributeType The type of the returned value */ T findSingleAttribute(Class attributeType); + /** + * Execute the query returning a list of scalar attribute values. + * + *
{@code
+   *
+   *   String sql =
+   *   " select (unit_price * order_qty) " +
+   *   " from o_order_detail " +
+   *   " where unit_price > ? " +
+   *   " order by (unit_price * order_qty) desc";
+   *
+   *   //
+   *   List lineAmounts = Ebean.createSqlQuery(sql)
+   *     .setParameter(1, 3)
+   *     .findSingleAttributeList(BigDecimal.class);
+   *
+   * }
+ * + *

+ * The attributeType can be any scalar type that Ebean supports (includes javax time types, Joda types etc). + *

+ * + * @param attributeType The type of the returned value + */ + List findSingleAttributeList(Class attributeType); + /** * The same as bind for named parameters. */ diff --git a/src/main/java/io/ebeaninternal/api/SpiEbeanServer.java b/src/main/java/io/ebeaninternal/api/SpiEbeanServer.java index 4de6f02e2..ed6fac793 100644 --- a/src/main/java/io/ebeaninternal/api/SpiEbeanServer.java +++ b/src/main/java/io/ebeaninternal/api/SpiEbeanServer.java @@ -239,6 +239,11 @@ public interface SpiEbeanServer extends EbeanServer, BeanLoader, BeanCollectionL */ T findSingleAttribute(SpiSqlQuery query, Class cls); + /** + * SqlQuery find single attribute list. + */ + List findSingleAttributeList(SpiSqlQuery query, Class cls); + /** * DTO findList query. */ diff --git a/src/main/java/io/ebeaninternal/server/core/DefaultServer.java b/src/main/java/io/ebeaninternal/server/core/DefaultServer.java index b2f75985b..14bb12e0f 100644 --- a/src/main/java/io/ebeaninternal/server/core/DefaultServer.java +++ b/src/main/java/io/ebeaninternal/server/core/DefaultServer.java @@ -1586,6 +1586,18 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer { } } + @Override + public List findSingleAttributeList(SpiSqlQuery query, Class cls) { + RelationalQueryRequest request = new RelationalQueryRequest(this, relationalQueryEngine, query, null); + try { + request.initTransIfRequired(); + return request.findSingleAttributeList(cls); + + } finally { + request.endTransIfRequired(); + } + } + @Override public T findSingleAttribute(SpiSqlQuery query, Class cls) { diff --git a/src/main/java/io/ebeaninternal/server/core/RelationalQueryEngine.java b/src/main/java/io/ebeaninternal/server/core/RelationalQueryEngine.java index 038f3842a..f6405aaa8 100644 --- a/src/main/java/io/ebeaninternal/server/core/RelationalQueryEngine.java +++ b/src/main/java/io/ebeaninternal/server/core/RelationalQueryEngine.java @@ -35,6 +35,11 @@ public interface RelationalQueryEngine { */ T findSingleAttribute(RelationalQueryRequest request, Class cls); + /** + * Find single attribute list. + */ + List findSingleAttributeList(RelationalQueryRequest request, Class cls); + /** * Collect SQL query execution statistics. */ diff --git a/src/main/java/io/ebeaninternal/server/core/RelationalQueryRequest.java b/src/main/java/io/ebeaninternal/server/core/RelationalQueryRequest.java index 221a3d36e..6324ffdfc 100644 --- a/src/main/java/io/ebeaninternal/server/core/RelationalQueryRequest.java +++ b/src/main/java/io/ebeaninternal/server/core/RelationalQueryRequest.java @@ -53,6 +53,10 @@ public final class RelationalQueryRequest extends AbstractSqlQueryRequest { } } + public List findSingleAttributeList(Class cls) { + return queryEngine.findSingleAttributeList(this, cls); + } + public T findSingleAttribute(Class cls) { return queryEngine.findSingleAttribute(this, cls); } diff --git a/src/main/java/io/ebeaninternal/server/query/DefaultRelationalQueryEngine.java b/src/main/java/io/ebeaninternal/server/query/DefaultRelationalQueryEngine.java index 9271ae624..b2fe0466e 100644 --- a/src/main/java/io/ebeaninternal/server/query/DefaultRelationalQueryEngine.java +++ b/src/main/java/io/ebeaninternal/server/query/DefaultRelationalQueryEngine.java @@ -92,6 +92,33 @@ public class DefaultRelationalQueryEngine implements RelationalQueryEngine { } } + @SuppressWarnings("unchecked") + @Override + public List findSingleAttributeList(RelationalQueryRequest request, Class cls) { + ScalarType scalarType = (ScalarType) binder.getScalarType(cls); + return findScalarList(request, scalarType); + } + + private List findScalarList(RelationalQueryRequest request, ScalarType scalarType) { + try { + request.executeSql(binder, SpiQuery.Type.ATTRIBUTE); + List list = new ArrayList<>(); + while (request.next()) { + request.incrementRows(); + list.add(scalarType.read(binder.createDataReader(request.getResultSet()))); + } + + request.logSummary(); + return list; + + } catch (Exception e) { + throw new PersistenceException(Message.msg("fetch.error", e.getMessage(), request.getSql()), e); + + } finally { + request.close(); + } + } + @SuppressWarnings("unchecked") @Override public T findSingleAttribute(RelationalQueryRequest request, Class cls) { diff --git a/src/main/java/io/ebeaninternal/server/querydefn/DefaultRelationalQuery.java b/src/main/java/io/ebeaninternal/server/querydefn/DefaultRelationalQuery.java index e5f81c2bf..ef58e2804 100644 --- a/src/main/java/io/ebeaninternal/server/querydefn/DefaultRelationalQuery.java +++ b/src/main/java/io/ebeaninternal/server/querydefn/DefaultRelationalQuery.java @@ -64,6 +64,11 @@ public class DefaultRelationalQuery implements SpiSqlQuery { return server.findSingleAttribute(this, cls); } + @Override + public List findSingleAttributeList(Class cls) { + return server.findSingleAttributeList(this, cls); + } + @Override public SqlRow findOne() { return server.findOne(this, null); diff --git a/src/test/java/io/ebeaninternal/api/TDSpiEbeanServer.java b/src/test/java/io/ebeaninternal/api/TDSpiEbeanServer.java index ab117a62d..1661403b9 100644 --- a/src/test/java/io/ebeaninternal/api/TDSpiEbeanServer.java +++ b/src/test/java/io/ebeaninternal/api/TDSpiEbeanServer.java @@ -462,6 +462,11 @@ public class TDSpiEbeanServer implements SpiEbeanServer { return null; } + @Override + public List findSingleAttributeList(SpiSqlQuery query, Class cls) { + return null; + } + @Override public SqlQuery createSqlQuery(String sql) { return null; diff --git a/src/test/java/org/tests/query/sqlquery/SqlQueryTests.java b/src/test/java/org/tests/query/sqlquery/SqlQueryTests.java index bd9b80191..2d4251db7 100644 --- a/src/test/java/org/tests/query/sqlquery/SqlQueryTests.java +++ b/src/test/java/org/tests/query/sqlquery/SqlQueryTests.java @@ -20,6 +20,20 @@ import static org.junit.Assert.assertEquals; public class SqlQueryTests extends BaseTestCase { + @Test + public void findSingleAttributeList_decimal() { + + ResetBasicData.reset(); + + String sql = "select (unit_price * order_qty) from o_order_detail where unit_price > ? order by (unit_price * order_qty) desc"; + + List lineAmounts = Ebean.createSqlQuery(sql) + .setParameter(1, 3) + .findSingleAttributeList(BigDecimal.class); + + assertThat(lineAmounts).isNotEmpty(); + } + @Test public void findSingleAttribute_decimal() {