mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
#1405 - ENH: Add SqlQuery.findSingleAttribute() ... for returning single scalar values via SqlQuery
This commit is contained in:
@@ -83,6 +83,23 @@ public interface SqlQuery extends Serializable {
|
||||
@Nonnull
|
||||
Optional<SqlRow> findOneOrEmpty();
|
||||
|
||||
/**
|
||||
* Execute the query returning a single scalar attribute.
|
||||
* <pre>@{code
|
||||
*
|
||||
* String sql = "select max(unit_price) from o_order_detail where order_qty > ?";
|
||||
*
|
||||
* BigDecimal maxPrice = Ebean.createSqlQuery(sql)
|
||||
* .setParameter(1, 2)
|
||||
* .findSingleAttribute(BigDecimal.class);
|
||||
*
|
||||
*
|
||||
* }</pre>
|
||||
*
|
||||
* @param attributeType The type of the returned value
|
||||
*/
|
||||
<T> T findSingleAttribute(Class<T> attributeType);
|
||||
|
||||
/**
|
||||
* The same as bind for named parameters.
|
||||
*/
|
||||
|
||||
@@ -234,6 +234,11 @@ public interface SpiEbeanServer extends EbeanServer, BeanLoader, BeanCollectionL
|
||||
*/
|
||||
void scopedTransactionExit(Object returnOrThrowable, int opCode);
|
||||
|
||||
/**
|
||||
* SqlQuery find single attribute.
|
||||
*/
|
||||
<T> T findSingleAttribute(SpiSqlQuery query, Class<T> cls);
|
||||
|
||||
/**
|
||||
* DTO findList query.
|
||||
*/
|
||||
|
||||
@@ -67,6 +67,7 @@ import io.ebeaninternal.api.SpiJsonContext;
|
||||
import io.ebeaninternal.api.SpiLogManager;
|
||||
import io.ebeaninternal.api.SpiQuery;
|
||||
import io.ebeaninternal.api.SpiQuery.Type;
|
||||
import io.ebeaninternal.api.SpiSqlQuery;
|
||||
import io.ebeaninternal.api.SpiSqlUpdate;
|
||||
import io.ebeaninternal.api.SpiTransaction;
|
||||
import io.ebeaninternal.api.SpiTransactionManager;
|
||||
@@ -1585,6 +1586,19 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T findSingleAttribute(SpiSqlQuery query, Class<T> cls) {
|
||||
|
||||
RelationalQueryRequest request = new RelationalQueryRequest(this, relationalQueryEngine, query, null);
|
||||
try {
|
||||
request.initTransIfRequired();
|
||||
return request.findSingleAttribute(cls);
|
||||
|
||||
} finally {
|
||||
request.endTransIfRequired();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> void findDtoEach(SpiDtoQuery<T> query, Consumer<T> consumer) {
|
||||
DtoQueryRequest<T> request = new DtoQueryRequest<>(this, dtoQueryEngine, query);
|
||||
|
||||
@@ -30,6 +30,11 @@ public interface RelationalQueryEngine {
|
||||
*/
|
||||
void findEach(RelationalQueryRequest request, Predicate<SqlRow> consumer);
|
||||
|
||||
/**
|
||||
* Find single attribute.
|
||||
*/
|
||||
<T> T findSingleAttribute(RelationalQueryRequest request, Class<T> cls);
|
||||
|
||||
/**
|
||||
* Collect SQL query execution statistics.
|
||||
*/
|
||||
|
||||
@@ -53,6 +53,10 @@ public final class RelationalQueryRequest extends AbstractSqlQueryRequest {
|
||||
}
|
||||
}
|
||||
|
||||
public <T> T findSingleAttribute(Class<T> cls) {
|
||||
return queryEngine.findSingleAttribute(this, cls);
|
||||
}
|
||||
|
||||
public void findEach(Consumer<SqlRow> consumer) {
|
||||
queryEngine.findEach(this, consumer);
|
||||
}
|
||||
@@ -104,4 +108,11 @@ public final class RelationalQueryRequest extends AbstractSqlQueryRequest {
|
||||
}
|
||||
}
|
||||
|
||||
public ResultSet getResultSet() {
|
||||
return resultSet;
|
||||
}
|
||||
|
||||
public void incrementRows() {
|
||||
rows++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,8 @@ import io.ebeaninternal.server.core.timezone.DataTimeZone;
|
||||
import io.ebeaninternal.server.expression.platform.DbExpressionHandler;
|
||||
import io.ebeaninternal.server.persist.platform.MultiValueBind;
|
||||
import io.ebeaninternal.server.type.DataBind;
|
||||
import io.ebeaninternal.server.type.DataReader;
|
||||
import io.ebeaninternal.server.type.RsetDataReader;
|
||||
import io.ebeaninternal.server.type.ScalarType;
|
||||
import io.ebeaninternal.server.type.TypeManager;
|
||||
import org.slf4j.Logger;
|
||||
@@ -18,6 +20,7 @@ import java.math.BigDecimal;
|
||||
import java.sql.CallableStatement;
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Types;
|
||||
import java.util.ArrayList;
|
||||
@@ -196,7 +199,7 @@ public class Binder {
|
||||
}
|
||||
}
|
||||
|
||||
private ScalarType<?> getScalarType(Class<?> clazz) {
|
||||
public ScalarType<?> getScalarType(Class<?> clazz) {
|
||||
ScalarType<?> type = typeManager.getScalarType(clazz);
|
||||
if (type == null) {
|
||||
throw new PersistenceException("No ScalarType registered for " + clazz);
|
||||
@@ -457,4 +460,8 @@ public class Binder {
|
||||
public DataBind dataBind(PreparedStatement stmt, Connection connection) {
|
||||
return new DataBind(dataTimeZone, stmt, connection);
|
||||
}
|
||||
|
||||
public DataReader createDataReader(ResultSet resultSet) {
|
||||
return new RsetDataReader(dataTimeZone, resultSet);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import io.ebeaninternal.server.core.Message;
|
||||
import io.ebeaninternal.server.core.RelationalQueryEngine;
|
||||
import io.ebeaninternal.server.core.RelationalQueryRequest;
|
||||
import io.ebeaninternal.server.persist.Binder;
|
||||
import io.ebeaninternal.server.type.ScalarType;
|
||||
|
||||
import javax.persistence.PersistenceException;
|
||||
import java.sql.SQLException;
|
||||
@@ -91,6 +92,35 @@ public class DefaultRelationalQueryEngine implements RelationalQueryEngine {
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <T> T findSingleAttribute(RelationalQueryRequest request, Class<T> cls) {
|
||||
|
||||
ScalarType<T> scalarType = (ScalarType<T>) binder.getScalarType(cls);
|
||||
return findScalar(request, scalarType);
|
||||
}
|
||||
|
||||
private <T> T findScalar(RelationalQueryRequest request, ScalarType<T> scalarType) {
|
||||
try {
|
||||
request.executeSql(binder, SpiQuery.Type.ATTRIBUTE);
|
||||
|
||||
T value = null;
|
||||
if (request.next()) {
|
||||
request.incrementRows();
|
||||
value = scalarType.read(binder.createDataReader(request.getResultSet()));
|
||||
}
|
||||
|
||||
request.logSummary();
|
||||
return value;
|
||||
|
||||
} catch (Exception e) {
|
||||
throw new PersistenceException(Message.msg("fetch.error", e.getMessage(), request.getSql()), e);
|
||||
|
||||
} finally {
|
||||
request.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SqlRow> findList(RelationalQueryRequest request) {
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package io.ebeaninternal.server.querydefn;
|
||||
|
||||
import io.ebean.EbeanServer;
|
||||
import io.ebean.SqlRow;
|
||||
import io.ebeaninternal.api.BindParams;
|
||||
import io.ebeaninternal.api.SpiEbeanServer;
|
||||
import io.ebeaninternal.api.SpiSqlQuery;
|
||||
|
||||
import java.util.List;
|
||||
@@ -17,7 +17,7 @@ public class DefaultRelationalQuery implements SpiSqlQuery {
|
||||
|
||||
private static final long serialVersionUID = -1098305779779591068L;
|
||||
|
||||
private final transient EbeanServer server;
|
||||
private final transient SpiEbeanServer server;
|
||||
|
||||
private String label;
|
||||
|
||||
@@ -39,16 +39,11 @@ public class DefaultRelationalQuery implements SpiSqlQuery {
|
||||
/**
|
||||
* Additional supply a query detail object.
|
||||
*/
|
||||
public DefaultRelationalQuery(EbeanServer server, String query) {
|
||||
public DefaultRelationalQuery(SpiEbeanServer server, String query) {
|
||||
this.server = server;
|
||||
this.query = query;
|
||||
}
|
||||
|
||||
public DefaultRelationalQuery setQuery(String query) {
|
||||
this.query = query;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void findEach(Consumer<SqlRow> consumer) {
|
||||
server.findEach(this, consumer, null);
|
||||
@@ -64,6 +59,11 @@ public class DefaultRelationalQuery implements SpiSqlQuery {
|
||||
return server.findList(this, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T findSingleAttribute(Class<T> cls) {
|
||||
return server.findSingleAttribute(this, cls);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SqlRow findOne() {
|
||||
return server.findOne(this, null);
|
||||
|
||||
@@ -32,7 +32,6 @@ public class ScalarTypeBigDecimal extends ScalarTypeBase<BigDecimal> {
|
||||
|
||||
@Override
|
||||
public BigDecimal read(DataReader dataReader) throws SQLException {
|
||||
|
||||
return dataReader.getBigDecimal();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user