mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
#917 - ENH: Add findNative() ... ala automatic mapping of native SQL into object graphs / paths.
This commit is contained in:
@@ -1012,6 +1012,30 @@ public final class Ebean {
|
||||
return serverMgr.getDefaultServer().find(beanType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a query using native SQL.
|
||||
* <p>
|
||||
* The native SQL can contain named parameters or positioned parameters.
|
||||
* </p>
|
||||
* <pre>{@code
|
||||
*
|
||||
* String sql = "select c.id, c.name from customer c where c.name like ? order by c.name";
|
||||
*
|
||||
* Query<Customer> query = ebeanServer.findNative(Customer.class, sql);
|
||||
* query.setParameter(1, "Rob%");
|
||||
*
|
||||
* List<Customer> customers = query.findList();
|
||||
*
|
||||
* }</pre>
|
||||
*
|
||||
* @param beanType The type of entity bean to fetch
|
||||
* @param nativeSql The SQL that can contain named or positioned parameters
|
||||
* @return The query to set parameters and execute
|
||||
*/
|
||||
public static <T> Query<T> findNative(Class<T> beanType, String nativeSql) {
|
||||
return serverMgr.getDefaultServer().findNative(beanType, nativeSql);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an Update query to perform a bulk update.
|
||||
* <p>
|
||||
|
||||
@@ -298,6 +298,28 @@ public interface EbeanServer {
|
||||
*/
|
||||
<T> Query<T> find(Class<T> beanType);
|
||||
|
||||
/**
|
||||
* Create a query using native SQL.
|
||||
* <p>
|
||||
* The native SQL can contain named parameters or positioned parameters.
|
||||
* </p>
|
||||
* <pre>{@code
|
||||
*
|
||||
* String sql = "select c.id, c.name from customer c where c.name like ? order by c.name";
|
||||
*
|
||||
* Query<Customer> query = ebeanServer.findNative(Customer.class, sql);
|
||||
* query.setParameter(1, "Rob%");
|
||||
*
|
||||
* List<Customer> customers = query.findList();
|
||||
*
|
||||
* }</pre>
|
||||
*
|
||||
* @param beanType The type of entity bean to fetch
|
||||
* @param nativeSql The SQL that can contain named or positioned parameters
|
||||
* @return The query to set parameters and execute
|
||||
*/
|
||||
<T> Query<T> findNative(Class<T> beanType, String nativeSql);
|
||||
|
||||
/**
|
||||
* Return the next unique identity value for a given bean type.
|
||||
* <p>
|
||||
|
||||
@@ -157,4 +157,10 @@ public class Finder<I, T> {
|
||||
return db().find(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a native sql query.
|
||||
*/
|
||||
public Query<T> nativeSql(String nativeSql) {
|
||||
return db().findNative(type, nativeSql);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -148,6 +148,16 @@ public interface SpiQuery<T> extends Query<T> {
|
||||
*/
|
||||
boolean isAutoTunable();
|
||||
|
||||
/**
|
||||
* Return true if this is a native sql query.
|
||||
*/
|
||||
boolean isNativeSql();
|
||||
|
||||
/**
|
||||
* Return the unmodified native sql query (with named params etc).
|
||||
*/
|
||||
String getNativeSql();
|
||||
|
||||
/**
|
||||
* Return the bean descriptor for this query.
|
||||
*/
|
||||
|
||||
@@ -897,6 +897,17 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
|
||||
return createQuery(beanType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Query<T> findNative(Class<T> beanType, String nativeSql) {
|
||||
BeanDescriptor<T> desc = getBeanDescriptor(beanType);
|
||||
if (desc == null) {
|
||||
throw new PersistenceException(beanType.getName() + " is NOT an Entity Bean registered with this server?");
|
||||
}
|
||||
DefaultOrmQuery<T> query = new DefaultOrmQuery<>(desc, this, expressionFactory);
|
||||
query.setNativeSql(nativeSql);
|
||||
return query;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Query<T> createNamedQuery(Class<T> beanType, String namedQuery) {
|
||||
BeanDescriptor<T> desc = getBeanDescriptor(beanType);
|
||||
|
||||
@@ -53,8 +53,6 @@ public final class OrmQueryRequest<T> extends BeanRequest implements BeanQueryRe
|
||||
|
||||
private final Boolean readOnly;
|
||||
|
||||
private final RawSql rawSql;
|
||||
|
||||
private LoadContext loadContext;
|
||||
|
||||
private PersistenceContext persistenceContext;
|
||||
@@ -73,7 +71,6 @@ public final class OrmQueryRequest<T> extends BeanRequest implements BeanQueryRe
|
||||
public OrmQueryRequest(SpiEbeanServer server, OrmQueryEngine queryEngine, SpiQuery<T> query, SpiTransaction t) {
|
||||
super(server, t);
|
||||
this.beanDescriptor = query.getBeanDescriptor();
|
||||
this.rawSql = query.getRawSql();
|
||||
this.finder = beanDescriptor.getBeanFinder();
|
||||
this.queryEngine = queryEngine;
|
||||
this.query = query;
|
||||
@@ -161,13 +158,17 @@ public final class OrmQueryRequest<T> extends BeanRequest implements BeanQueryRe
|
||||
this.queryPlanKey = query.prepare(this);
|
||||
}
|
||||
|
||||
public boolean isNativeSql() {
|
||||
return query.isNativeSql();
|
||||
}
|
||||
|
||||
public boolean isRawSql() {
|
||||
return rawSql != null;
|
||||
return query.isRawSql();
|
||||
}
|
||||
|
||||
public DeployParser createDeployParser() {
|
||||
if (rawSql != null) {
|
||||
return new DeployPropertyParserMap(rawSql.getColumnMapping().getMapping());
|
||||
if (query.isRawSql()) {
|
||||
return new DeployPropertyParserMap(query.getRawSql().getColumnMapping().getMapping());
|
||||
} else {
|
||||
return beanDescriptor.createDeployPropertyParser();
|
||||
}
|
||||
@@ -531,4 +532,5 @@ public final class OrmQueryRequest<T> extends BeanRequest implements BeanQueryRe
|
||||
public void setDefaultFetchBuffer(int fetchSize) {
|
||||
query.setDefaultFetchBuffer(fetchSize);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -89,6 +89,7 @@ import java.sql.Types;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -204,6 +205,16 @@ public class BeanDescriptor<T> implements MetaBeanInfo, BeanType<T> {
|
||||
*/
|
||||
protected final LinkedHashMap<String, BeanProperty> propMap;
|
||||
|
||||
/**
|
||||
* Map of DB column to property path (for nativeSql mapping).
|
||||
*/
|
||||
private final Map<String, String> columnPath = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Map of related table to assoc property (for nativeSql mapping).
|
||||
*/
|
||||
private final Map<String, BeanPropertyAssoc<?>> tablePath = new HashMap<>();
|
||||
|
||||
/**
|
||||
* The type of bean this describes.
|
||||
*/
|
||||
@@ -673,6 +684,7 @@ public class BeanDescriptor<T> implements MetaBeanInfo, BeanType<T> {
|
||||
if (!prop.isId()) {
|
||||
prop.initialise();
|
||||
}
|
||||
prop.registerColumn(this, null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -699,6 +711,16 @@ public class BeanDescriptor<T> implements MetaBeanInfo, BeanType<T> {
|
||||
}
|
||||
}
|
||||
|
||||
void registerColumn(String dbColumn, String path) {
|
||||
columnPath.put(dbColumn.toLowerCase(), path);
|
||||
}
|
||||
|
||||
void registerTable(String baseTable, BeanPropertyAssoc<?> assocProperty) {
|
||||
if (baseTable != null) {
|
||||
tablePath.put(baseTable.toLowerCase(), assocProperty);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform last initialisation for the descriptor.
|
||||
*/
|
||||
@@ -1081,7 +1103,7 @@ public class BeanDescriptor<T> implements MetaBeanInfo, BeanType<T> {
|
||||
* Prepare the query for multi-tenancy check for document store only use.
|
||||
*/
|
||||
public void prepareQuery(SpiQuery<T> query) {
|
||||
if (tenant != null) {
|
||||
if (tenant != null && !query.isNativeSql()) {
|
||||
Object tenantId = ebeanServer.currentTenantId();
|
||||
if (tenantId != null) {
|
||||
query.where().eq(tenant.getName(), tenantId);
|
||||
@@ -2163,6 +2185,23 @@ public class BeanDescriptor<T> implements MetaBeanInfo, BeanType<T> {
|
||||
return chain.add(property).build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the property path given the db table and column.
|
||||
*/
|
||||
public String findBeanPath(String tableName, String columnName) {
|
||||
if (tableName.length() == 0 || tableName.equalsIgnoreCase(baseTable)) {
|
||||
return columnPath.get(columnName);
|
||||
}
|
||||
BeanPropertyAssoc<?> assocProperty = tablePath.get(tableName);
|
||||
if (assocProperty != null) {
|
||||
String relativePath = assocProperty.getTargetDescriptor().findBeanPath(tableName, columnName);
|
||||
if (relativePath != null) {
|
||||
return SplitName.add(assocProperty.getName(), relativePath);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a BeanProperty including searching the inheritance hierarchy.
|
||||
* <p>
|
||||
|
||||
@@ -19,6 +19,7 @@ import com.avaje.ebeaninternal.server.el.ElPropertyValue;
|
||||
import com.avaje.ebeaninternal.server.lib.util.StringHelper;
|
||||
import com.avaje.ebeaninternal.server.properties.BeanPropertyGetter;
|
||||
import com.avaje.ebeaninternal.server.properties.BeanPropertySetter;
|
||||
import com.avaje.ebeaninternal.server.query.SplitName;
|
||||
import com.avaje.ebeaninternal.server.query.SqlBeanLoad;
|
||||
import com.avaje.ebeaninternal.server.query.SqlJoinType;
|
||||
import com.avaje.ebeaninternal.server.text.json.ReadJson;
|
||||
@@ -1424,4 +1425,10 @@ public class BeanProperty implements ElPropertyValue, Property {
|
||||
public void merge(EntityBean bean, EntityBean existing) {
|
||||
// do nothing unless Many property
|
||||
}
|
||||
|
||||
public void registerColumn(BeanDescriptor<?> desc, String prefix) {
|
||||
if (dbColumn != null) {
|
||||
desc.registerColumn(dbColumn, SplitName.add(prefix, name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -275,6 +275,26 @@ public class BeanPropertyAssocOne<T> extends BeanPropertyAssoc<T> {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerColumn(BeanDescriptor<?> desc, String prefix) {
|
||||
if (embedded) {
|
||||
for (BeanProperty prop : embeddedProps) {
|
||||
prop.registerColumn(desc, SplitName.add(prefix, name));
|
||||
}
|
||||
} else {
|
||||
if (targetIdProperty != null) {
|
||||
BeanDescriptor<T> target = getTargetDescriptor();
|
||||
String basePath = SplitName.add(prefix, name);
|
||||
if (dbColumn != null) {
|
||||
BeanProperty idProperty = target.getIdProperty();
|
||||
desc.registerColumn(dbColumn, SplitName.add(basePath, idProperty.getName()));
|
||||
}
|
||||
|
||||
desc.registerTable(target.getBaseTable(), this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return meta data for the deployment of the embedded bean specific to this
|
||||
* property.
|
||||
|
||||
@@ -24,6 +24,12 @@ import com.avaje.ebeaninternal.server.querydefn.OrmQueryDetail;
|
||||
import com.avaje.ebeaninternal.server.querydefn.OrmQueryLimitRequest;
|
||||
|
||||
import javax.persistence.PersistenceException;
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.ResultSetMetaData;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
@@ -343,13 +349,58 @@ class CQueryBuilder {
|
||||
*/
|
||||
private SqlTree createSqlTree(OrmQueryRequest<?> request, CQueryPredicates predicates, CQueryHistorySupport historySupport, CQueryDraftSupport draftSupport) {
|
||||
|
||||
if (request.isNativeSql()) {
|
||||
return createNativeSqlTree(request, predicates);
|
||||
}
|
||||
if (request.isRawSql()) {
|
||||
return createRawSqlSqlTree(request, predicates);
|
||||
}
|
||||
|
||||
return new SqlTreeBuilder(tableAliasPlaceHolder, columnAliasPrefix, request, predicates, historySupport, draftSupport).build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the SqlTree by reading the ResultSetMetaData and mapping table/columns to bean property paths.
|
||||
*/
|
||||
private SqlTree createNativeSqlTree(OrmQueryRequest<?> request, CQueryPredicates predicates) {
|
||||
|
||||
SpiQuery<?> query = request.getQuery();
|
||||
|
||||
// parse named parameters returning the final sql to execute
|
||||
String sql = predicates.parseBindParams(query.getNativeSql());
|
||||
query.setGeneratedSql(sql);
|
||||
|
||||
Connection connection = request.getTransaction().getConnection();
|
||||
|
||||
BeanDescriptor<?> desc = request.getBeanDescriptor();
|
||||
try {
|
||||
PreparedStatement statement = connection.prepareStatement(sql);
|
||||
predicates.bind(statement, connection);
|
||||
|
||||
List<String> propertyNames = new ArrayList<>();
|
||||
|
||||
ResultSet resultSet = statement.executeQuery();
|
||||
ResultSetMetaData metaData = resultSet.getMetaData();
|
||||
int cols = 1 + metaData.getColumnCount();
|
||||
for (int i = 1; i < cols; i++) {
|
||||
String tableName = metaData.getTableName(i).toLowerCase();
|
||||
String columnName = metaData.getColumnName(i).toLowerCase();
|
||||
String path = desc.findBeanPath(tableName, columnName);
|
||||
if (path != null) {
|
||||
propertyNames.add(path);
|
||||
} else {
|
||||
propertyNames.add(RawSqlBuilder.IGNORE_COLUMN);
|
||||
}
|
||||
}
|
||||
|
||||
RawSql rawSql = RawSqlBuilder.resultSet(resultSet, propertyNames.toArray(new String[propertyNames.size()]));
|
||||
query.setRawSql(rawSql);
|
||||
return createRawSqlSqlTree(request, predicates);
|
||||
|
||||
} catch (SQLException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private SqlTree createRawSqlSqlTree(OrmQueryRequest<?> request, CQueryPredicates predicates) {
|
||||
|
||||
BeanDescriptor<?> descriptor = request.getBeanDescriptor();
|
||||
@@ -376,8 +427,12 @@ class CQueryBuilder {
|
||||
throw new PersistenceException("Property [" + propertyName + "] not found on " + descriptor.getFullName());
|
||||
} else {
|
||||
BeanProperty beanProperty = el.getBeanProperty();
|
||||
if (beanProperty.isId() || beanProperty.isDiscriminator()) {
|
||||
// For @Id properties we chop off the last part of the path
|
||||
if (beanProperty.isId()) {
|
||||
if (propertyName.contains(".")) {
|
||||
// For @Id properties we chop off the last part of the path
|
||||
propertyName = SplitName.parent(propertyName);
|
||||
}
|
||||
} else if (beanProperty.isDiscriminator()) {
|
||||
propertyName = SplitName.parent(propertyName);
|
||||
} else if (beanProperty instanceof BeanPropertyAssocOne<?>) {
|
||||
String msg = "Column [" + column.getDbColumn() + "] mapped to complex Property[" + propertyName + "]";
|
||||
@@ -436,9 +491,11 @@ class CQueryBuilder {
|
||||
|
||||
SpiQuery<?> query = request.getQuery();
|
||||
|
||||
RawSql rawSql = query.getRawSql();
|
||||
if (rawSql != null) {
|
||||
return rawSqlHandler.buildSql(request, predicates, rawSql.getSql());
|
||||
if (query.isNativeSql()) {
|
||||
return new SqlLimitResponse(query.getGeneratedSql(), false);
|
||||
}
|
||||
if (query.isRawSql()) {
|
||||
return rawSqlHandler.buildSql(request, predicates, query.getRawSql().getSql());
|
||||
}
|
||||
|
||||
BeanPropertyAssocMany<?> manyProp = select.getManyProperty();
|
||||
|
||||
@@ -136,16 +136,19 @@ public class CQueryPredicates {
|
||||
dataBind.append(", ");
|
||||
}
|
||||
|
||||
int asOfTableCount = request.getQueryPlan().getAsOfTableCount();
|
||||
if (asOfTableCount > 0) {
|
||||
// bind the asOf value for each table alias as part of the from/join clauses
|
||||
// there is one effective date predicate per table alias
|
||||
Timestamp asOf = query.getAsOf();
|
||||
dataBind.append("asOf ").append(asOf);
|
||||
for (int i = 0; i < asOfTableCount * binder.getAsOfBindCount(); i++) {
|
||||
binder.bindObject(dataBind, asOf);
|
||||
CQueryPlan queryPlan = request.getQueryPlan();
|
||||
if (queryPlan != null) {
|
||||
int asOfTableCount = queryPlan.getAsOfTableCount();
|
||||
if (asOfTableCount > 0) {
|
||||
// bind the asOf value for each table alias as part of the from/join clauses
|
||||
// there is one effective date predicate per table alias
|
||||
Timestamp asOf = query.getAsOf();
|
||||
dataBind.append("asOf ").append(asOf);
|
||||
for (int i = 0; i < asOfTableCount * binder.getAsOfBindCount(); i++) {
|
||||
binder.bindObject(dataBind, asOf);
|
||||
}
|
||||
dataBind.append(", ");
|
||||
}
|
||||
dataBind.append(", ");
|
||||
}
|
||||
|
||||
if (idValue != null) {
|
||||
@@ -184,18 +187,33 @@ public class CQueryPredicates {
|
||||
}
|
||||
}
|
||||
|
||||
public String parseBindParams(String sql) {
|
||||
if (bindParams != null && bindParams.requiresNamedParamsPrepare()) {
|
||||
return BindParamsParser.parse(bindParams, sql);
|
||||
} else {
|
||||
return sql;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert named parameters into an OrderedList.
|
||||
*/
|
||||
private void buildBindWhereRawSql(boolean buildSql) {
|
||||
|
||||
if (!buildSql && query.isRawSql() && bindParams != null && bindParams.requiresNamedParamsPrepare()) {
|
||||
// RawSql query hit cached query plan. Need to convert
|
||||
// named parameters into positioned parameters so that
|
||||
// the named parameters are bound
|
||||
RawSql.Sql sql = query.getRawSql().getSql();
|
||||
String s = sql.isParsed() ? sql.getPreWhere() : sql.getUnparsedSql();
|
||||
BindParamsParser.parse(bindParams, s);
|
||||
if (!buildSql && bindParams != null && bindParams.requiresNamedParamsPrepare()) {
|
||||
if (query.isNativeSql()) {
|
||||
// convert named params into positioned params
|
||||
String sql = query.getNativeSql();
|
||||
BindParamsParser.parse(bindParams, sql);
|
||||
|
||||
} else if (query.isRawSql()) {
|
||||
// RawSql query hit cached query plan. Need to convert
|
||||
// named parameters into positioned parameters so that
|
||||
// the named parameters are bound
|
||||
RawSql.Sql sql = query.getRawSql().getSql();
|
||||
String s = sql.isParsed() ? sql.getPreWhere() : sql.getUnparsedSql();
|
||||
BindParamsParser.parse(bindParams, s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
package com.avaje.ebeaninternal.server.query;
|
||||
|
||||
import com.avaje.ebeaninternal.api.CQueryPlanKey;
|
||||
|
||||
/**
|
||||
* QueryPlanKey for native sql queries.
|
||||
*/
|
||||
public class NativeSqlQueryPlanKey implements CQueryPlanKey {
|
||||
|
||||
private final String sql;
|
||||
|
||||
public NativeSqlQueryPlanKey(String sql) {
|
||||
this.sql = sql;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return getPartialKey();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return as a partial key. For rawSql hash the sql is part of the key and as such
|
||||
* needs to be included in order to have a complete key. Typically the MD5 of the sql
|
||||
* can be used as a short form proxy for the actual sql.
|
||||
*/
|
||||
public String getPartialKey() {
|
||||
return hashCode() + "_n";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
NativeSqlQueryPlanKey that = (NativeSqlQueryPlanKey) o;
|
||||
return sql.equals(that.sql);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return sql.hashCode();
|
||||
}
|
||||
}
|
||||
@@ -26,6 +26,7 @@ import com.avaje.ebeaninternal.server.deploy.TableJoin;
|
||||
import com.avaje.ebeaninternal.server.expression.DefaultExpressionList;
|
||||
import com.avaje.ebeaninternal.server.expression.SimpleExpression;
|
||||
import com.avaje.ebeaninternal.server.query.CancelableQuery;
|
||||
import com.avaje.ebeaninternal.server.query.NativeSqlQueryPlanKey;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
import java.util.ArrayList;
|
||||
@@ -234,6 +235,8 @@ public class DefaultOrmQuery<T> implements SpiQuery<T> {
|
||||
|
||||
private OrmUpdateProperties updateProperties;
|
||||
|
||||
private String nativeSql;
|
||||
|
||||
public DefaultOrmQuery(BeanDescriptor<T> desc, EbeanServer server, ExpressionFactory expressionFactory) {
|
||||
this.beanDescriptor = desc;
|
||||
this.beanType = desc.getBeanType();
|
||||
@@ -242,6 +245,10 @@ public class DefaultOrmQuery<T> implements SpiQuery<T> {
|
||||
this.detail = new OrmQueryDetail();
|
||||
}
|
||||
|
||||
public void setNativeSql(String nativeSql) {
|
||||
this.nativeSql = nativeSql;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BeanDescriptor<T> getBeanDescriptor() {
|
||||
return beanDescriptor;
|
||||
@@ -259,7 +266,7 @@ public class DefaultOrmQuery<T> implements SpiQuery<T> {
|
||||
|
||||
@Override
|
||||
public boolean isAutoTunable() {
|
||||
return beanDescriptor.isAutoTunable();
|
||||
return nativeSql == null && beanDescriptor.isAutoTunable();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -901,14 +908,27 @@ public class DefaultOrmQuery<T> implements SpiQuery<T> {
|
||||
*/
|
||||
CQueryPlanKey createQueryPlanKey() {
|
||||
|
||||
queryPlanKey = new OrmQueryPlanKey(m2mIncludeJoin, type, detail, maxRows, firstRow,
|
||||
disableLazyLoading, orderBy,
|
||||
distinct, sqlDistinct, mapKey, id, bindParams, whereExpressions, havingExpressions,
|
||||
temporalMode, forUpdate, rootTableAlias, rawSql, updateProperties);
|
||||
|
||||
if (isNativeSql()) {
|
||||
queryPlanKey = new NativeSqlQueryPlanKey(nativeSql);
|
||||
} else {
|
||||
queryPlanKey = new OrmQueryPlanKey(m2mIncludeJoin, type, detail, maxRows, firstRow,
|
||||
disableLazyLoading, orderBy,
|
||||
distinct, sqlDistinct, mapKey, id, bindParams, whereExpressions, havingExpressions,
|
||||
temporalMode, forUpdate, rootTableAlias, rawSql, updateProperties);
|
||||
}
|
||||
return queryPlanKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNativeSql() {
|
||||
return nativeSql != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNativeSql() {
|
||||
return nativeSql;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare the query which prepares any expressions (sub-query expressions etc) and calculates the query plan key.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user