据我所知,Hybris使用FlexibleSearchQuery来查询数据。因此,要查询数据库,我需要将FlexibleSearchQuery转换为SQL。我仍然不知道Hybris是怎么做到的。你能帮助我理解吗?
我的堆栈跟踪代码如下:
我明白了:TranslatedQuery tQuery(类:FlexibleSearch方法:executeSearch)= this.cacheKey.tq(类:FlexibleSearchCacheUnit方法:计算)。
那么,this.cacheKey.tq值来自哪里?
PreparedStatementImpl executeQuery
public ResultSet executeQuery() throws SQLException {
if (this.isLoggingActivated()) {
long startTime = System.currentTimeMillis();
ResultSet var5;
try {
var5 = this.wrapResultSet(this.prepStmtPassthru.executeQuery());
} catch (SQLException var9) {
this.getConnection().notifyError(var9);
this.getConnection().logError(var9, "error executing query");
throw var9;
} finally {
this.connection.getDataSource().getLogUtils().logElapsed(Thread.currentThread().getId(), this.connection.getConnectionID(), startTime, "statement", this.preparedQueryWithoutStackTrace, this.assembleQueryFromPreparedStatement());
}
return var5;
} else {
try {
return this.wrapResultSet(this.prepStmtPassthru.executeQuery());
} catch (SQLException var11) {
this.getConnection().notifyError(var11);
this.getConnection().logError(var11, "error executing query");
throw var11;
}
}
}
FlexibleSearchExecutor execute
public SearchResult execute(int start, int count, boolean dontNeedTotal, TranslatedQuery translatedQuery, List<Class<?>> resultClasses, Map values, PK languagePK, int prefetchSize, Set<PK> prefetchLanguages) {
ConversionMetaInformation conversionResult = this.convertResultClasses(resultClasses);
ExecutableQuery executableQuery = this.getExecutableQuery(translatedQuery, values, languagePK);
JDBCValueMappings jdbcVM = JDBCValueMappings.getInstance();
LimitStatementBuilder limitBuilder = this.limitStatementFactory.getLimitStatementBuilder(executableQuery, start, count);
Connection connection = null;
PreparedStatement statement = null;
ResultSet resultSet = null;
String query = null;
SearchResult result;
try {
String errorMessageSecondPart;
try {
connection = this.tenant.getDataSource().getConnection();
if (this.isNeedTotalAndCountIsZero(count, dontNeedTotal)) {
int totalCount = jdbcVM.getTotalCountFromCountQuery(connection, executableQuery.getCountSQL(), executableQuery.getCountValueList());
result = SQLSearchResultFactory.createCountOnlyResult(totalCount, start, count, executableQuery.getSQL(), executableQuery.getValueList());
} else {
query = limitBuilder.getModifiedStatement();
statement = connection.prepareStatement(query);
jdbcVM.fillStatement(statement, limitBuilder.getModifiedStatementValues());
long t1 = 0L;
long t2 = 0L;
long t3 = 0L;
long t4 = 0L;
if (LOG.isDebugEnabled()) {
t1 = System.currentTimeMillis();
}
resultSet = statement.executeQuery();
if (LOG.isDebugEnabled()) {
t2 = System.currentTimeMillis();
}
int _start = limitBuilder.getOriginalStart();
int _count = limitBuilder.getOriginalCount();
if (limitBuilder.hasDbEngineLimitSupport()) {
_start = 0;
_count = -1;
}
if (LOG.isDebugEnabled()) {
t3 = System.currentTimeMillis();
}
RowFetchResult rowFetchResult = jdbcVM.getQueryResults(resultSet, conversionResult.getConvertedClasses(), _start, _count);
if (LOG.isDebugEnabled()) {
t4 = System.currentTimeMillis();
}
int totalCount = dontNeedTotal ? rowFetchResult.rows.size() : jdbcVM.getTotalCount(resultSet, rowFetchResult, start, count, connection, executableQuery, limitBuilder.hasDbEngineLimitSupport());
if (LOG.isDebugEnabled()) {
LOG.debug(this.getInfoForLogging(executableQuery.getSQL(), limitBuilder.getModifiedStatement(), conversionResult.getConvertedClasses(), executableQuery.getValueList(), ", original range=[" + limitBuilder.getOriginalStart() + "," + limitBuilder.getOriginalCount() + "], rowcount=" + totalCount + ", query=" + (t2 - t1) / 1000L + "ms, fetch=" + (t4 - t3) / 1000L + "ms"));
}
result = SQLSearchResultFactory.createCacheable(new CacheableResultHolder(rowFetchResult, prefetchSize, prefetchLanguages, conversionResult), totalCount, start, count, limitBuilder.getModifiedStatement(), executableQuery.getValueList());
}
} catch (IllegalArgumentException var35) {
errorMessageSecondPart = Config.getBoolean("flexible.search.exception.show.query.details", false) ? var35.getMessage() + " query = '" + executableQuery.getSQL() + "', values = " + executableQuery.getValueList() : "enable the property 'flexible.search.exception.show.query.details' for more details";
throw new FlexibleSearchException(var35, "wrong flexible search parameter - " + errorMessageSecondPart, 0);
} catch (SQLException var36) {
errorMessageSecondPart = Config.getBoolean("flexible.search.exception.show.query.details", false) ? var36.getMessage() + " query = '" + query + "', values = " + executableQuery.getValueList() : "enable the property 'flexible.search.exception.show.query.details' for more details";
throw new FlexibleSearchException(var36, "SQL search error - " + errorMessageSecondPart, 0);
}
} finally {
Utilities.tryToCloseJDBC(connection, statement, resultSet);
}
return result;
}
FlexibleSearch executeSearch
protected SearchResult executeSearch(TranslatedQuery tQuery, Map values, PK langPK, List<Class<?>> resultClasses, boolean dontNeedTotal, int start, int count, int prefetchSize, Set<PK> prefetchLanguages, boolean doExecuteQuery) throws FlexibleSearchException {
return doExecuteQuery ? this.fsExecutor.execute(start, count, dontNeedTotal, tQuery, resultClasses, values, langPK, prefetchSize, prefetchLanguages) : this.fsExecutor.simulate(start, count, tQuery, values, langPK);
}
FlexibleSearchCacheUnit compute
public final Object compute() throws FlexibleSearchException {
this.usedCachedResult = false;
StandardSearchResult ret = (StandardSearchResult)this.fs.executeSearch(this.cacheKey.tq, this.values, this.cacheKey.langPK, Arrays.asList(this.cacheKey.resultClasses), this.cacheKey.hasModifier(1), this.cacheKey.start, this.cacheKey.count, this.prefetchSize, this.prefetchLanguages, this.cacheKey.hasModifier(2));
ret.setUnitHash(System.identityHashCode(this));
return ret;
}
AbstractCacheUnit privateGetNoLock
private final Object privateGetNoLock() throws Exception {
Object ret = this.value;
if (this.isValueUnknown(ret)) {
ret = this.compute();
this.value = ret;
}
return ret;
}
AbstractCacheUnit privateGet
private final Object privateGet() throws Exception {
return this.getTransactionAwareCache().isForceExclusiveComputation(this) ? this.privateGetSynchronized() : this.privateGetNoLock();
}
AbstractCacheUnit get
public final Object get() throws Exception {
if (!this.useCache()) {
return this.computeUncached();
} else {
TransactionAwareCache transactionAwareCache = this.getTransactionAwareCache();
boolean success = false;
AbstractCacheUnit valueUnit = transactionAwareCache.getOrAddUnit(this);
Object ret = valueUnit.value;
try {
ret = this.isValueUnknown(ret) ? valueUnit.privateGet() : ret;
success = true;
} catch (CacheValueLoadException var9) {
if (var9.getCause() instanceof Exception) {
throw (Exception)var9.getCause();
}
throw var9;
} finally {
if (!success) {
transactionAwareCache.removeUnit(valueUnit);
}
}
return ret;
}
}
FlexibleSearchCacheUnit myGet
public final StandardSearchResult myGet() throws Exception {
StandardSearchResult ret = (StandardSearchResult)this.get();
ret.setFromCache(this.usedCachedResult);
return ret;
}
FlexibleSearch search
public SearchResult search(SessionContext _ctx, String query, Map values, List resultClasses, boolean failOnUnknownFields, boolean dontNeedTotal, int start, int count) throws FlexibleSearchException {
TranslatedQuery tQuery = null;
int prefetchSize = this.getSearchPrefetchSize(_ctx);
if (LOG.isDebugEnabled()) {
LOG.debug(this.getSearchDebug(_ctx, query, resultClasses, failOnUnknownFields, dontNeedTotal, start, count, prefetchSize));
}
boolean doExecuteQuery = !this.disableExecution(_ctx);
SessionContext localCtx = null;
SearchResult var22;
try {
if (_ctx != null) {
localCtx = JaloSession.getCurrentSession(this.getTenant()).createLocalSessionContext(_ctx);
localCtx.setAttribute("disableExecution", Boolean.FALSE);
}
PK langPK = this.getSearchLangPK(localCtx);
tQuery = this.translate(localCtx, this.getRestrictionPrincipal(localCtx), query, values != null ? values.size() : 0, langPK != null, failOnUnknownFields, this.disableRestrictions(localCtx), this.disablePrincipalGroupRestrictions(localCtx), values);
Map _values = tQuery.removeUnusedValues(this.translatePathValueKeys(localCtx, tQuery.getValueKeys(), new CaseInsensitiveParameterMap(values != null ? values : Collections.EMPTY_MAP)));
Set<PK> queryTCs = tQuery.getTypePKs();
Set<Integer> beanTCs = new HashSet(queryTCs.size() * 4);
PersistenceManager pm = this.getTenant().getPersistenceManager();
Iterator var19 = queryTCs.iterator();
while(var19.hasNext()) {
PK typePK = (PK)var19.next();
beanTCs.addAll(pm.getBeanTypeCodes(typePK));
}
if (beanTCs.isEmpty()) {
throw new JaloInvalidParameterException("empty bean typcode list ( typePKs = " + tQuery.getTypePKs() + ", query = " + tQuery.getSQLTemplate() + " )", 0);
}
try {
if (!this.isCachingDisabled(localCtx)) {
int ttl = this.getTTL(localCtx);
FlexibleSearch.FlexibleSearchCacheKey cacheKey = this.createCacheKey(resultClasses, dontNeedTotal, start, count, tQuery, doExecuteQuery, langPK, _values, beanTCs, ttl);
FlexibleSearchCacheUnit cacheUnit = this.createCacheUnit(prefetchSize, WrapperFactory.getPrefetchLanguages(localCtx), _values, cacheKey);
var22 = this.wrapSearchResult(cacheUnit.myGet());
return var22;
}
var22 = this.wrapSearchResult(this.executeSearch(tQuery, _values, langPK, resultClasses, dontNeedTotal, start, count, prefetchSize, WrapperFactory.getPrefetchLanguages(localCtx), doExecuteQuery));
} catch (FlexibleSearchException var28) {
throw var28;
} catch (Exception var29) {
throw new FlexibleSearchException(var29, var29.getMessage(), 0);
}
} catch (FlexibleSearchException var30) {
LOG.error("Flexible search error occured...");
if (tQuery == null) {
LOG.error("Query translation was not successful.");
}
throw var30;
} catch (JaloItemNotFoundException var31) {
throw new JaloInternalException(var31, "cannot get type by translated query type pk", 0);
} finally {
if (localCtx != null) {
JaloSession.getCurrentSession(this.getTenant()).removeLocalSessionContext();
}
}
return var22;
}
FlexibleSearch search
public SearchResult search(String query, Map values, List resultClasses, boolean failOnUnknownFields, boolean dontNeedTotal, int start, int count) throws FlexibleSearchException {
return this.search(JaloSession.hasCurrentSession() ? this.getSession().getSessionContext() : null, query, values, resultClasses, failOnUnknownFields, dontNeedTotal, start, count);
}
DefaultFlexibleSearchService$2 execute
private <T> de.hybris.platform.jalo.SearchResult<T> getJaloResult(final FlexibleSearchQuery query) {
return (de.hybris.platform.jalo.SearchResult)this.getSessionService().executeInLocalView(new SessionExecutionBody() {
public de.hybris.platform.jalo.SearchResult<T> execute() {
DefaultFlexibleSearchService.this.getQueryPreprocessorRegistry().executeAllPreprocessors(query);
Map queryParams = (Map)DefaultFlexibleSearchService.this.toPersistenceLayer(query.getQueryParameters());
try {
return FlexibleSearch.getInstance().search(query.getQuery(), queryParams, this.convertModelClassList(query), query.isFailOnUnknownFields(), !query.isNeedTotal(), query.getStart(), query.getCount());
} catch (FlexibleSearchException var3) {
throw new de.hybris.platform.servicelayer.search.exceptions.FlexibleSearchException(var3.getMessage(), var3);
}
}
private List<Class> convertModelClassList(FlexibleSearchQuery queryx) {
List<Class> resultClassList = new ArrayList(queryx.getResultClassList().size());
Iterator var4 = queryx.getResultClassList().iterator();
while(var4.hasNext()) {
Class modelClass = (Class)var4.next();
resultClassList.add(DefaultFlexibleSearchService.this.getModelService().getModelTypeClass(modelClass));
}
return resultClassList;
}
});
}
DefaultFlexibleSearchService$2 execute
DefaultSessionService executeInLocalView
public Object executeInLocalView(SessionExecutionBody body) {
Object var3;
try {
this.getOrCreateCurrentJaloSession().createLocalSessionContext();
var3 = body.execute();
} finally {
this.getOrCreateCurrentJaloSession().removeLocalSessionContext();
}
return var3;
}
DefaultFlexibleSearchService getJaloResult
private <T> de.hybris.platform.jalo.SearchResult<T> getJaloResult(final FlexibleSearchQuery query) {
return (de.hybris.platform.jalo.SearchResult)this.getSessionService().executeInLocalView(new SessionExecutionBody() {
public de.hybris.platform.jalo.SearchResult<T> execute() {
DefaultFlexibleSearchService.this.getQueryPreprocessorRegistry().executeAllPreprocessors(query);
Map queryParams = (Map)DefaultFlexibleSearchService.this.toPersistenceLayer(query.getQueryParameters());
try {
return FlexibleSearch.getInstance().search(query.getQuery(), queryParams, this.convertModelClassList(query), query.isFailOnUnknownFields(), !query.isNeedTotal(), query.getStart(), query.getCount());
} catch (FlexibleSearchException var3) {
throw new de.hybris.platform.servicelayer.search.exceptions.FlexibleSearchException(var3.getMessage(), var3);
}
}
private List<Class> convertModelClassList(FlexibleSearchQuery queryx) {
List<Class> resultClassList = new ArrayList(queryx.getResultClassList().size());
Iterator var4 = queryx.getResultClassList().iterator();
while(var4.hasNext()) {
Class modelClass = (Class)var4.next();
resultClassList.add(DefaultFlexibleSearchService.this.getModelService().getModelTypeClass(modelClass));
}
return resultClassList;
}
});
}
DefaultFlexibleSearchService search
public <T> SearchResult<T> search(FlexibleSearchQuery query) {
ServicesUtil.validateParameterNotNull(query, "The 'query' is null!");
de.hybris.platform.jalo.SearchResult<T> jaloResult = this.getJaloResult(query);
if (jaloResult.getCount() == 0) {
return this.createEmptyResult(jaloResult);
} else {
return jaloResult instanceof StandardSearchResult ? this.wrapOrConvert(query, (StandardSearchResult)jaloResult, () -> {
return this.convert(jaloResult);
}) : this.convert(jaloResult);
}
}
DefaultPagedFlexibleSearchService search
public <T> SearchPageData<T> search(final String query, final Map<String, ?> queryParams, final PageableData pageableData)
{
validateParameterNotNull(query, "query cannot be null");
validateParameterNotNull(pageableData, "pageableData cannot be null");
Assert.isTrue(pageableData.getCurrentPage() >= 0, "pageableData current page must be zero or greater");
Assert.isTrue(pageableData.getPageSize() > 0, "pageableData page size must be greater than zero");
final FlexibleSearchQuery searchQuery = new FlexibleSearchQuery(query);
if (queryParams != null && !queryParams.isEmpty())
{
searchQuery.addQueryParameters(queryParams);
}
searchQuery.setNeedTotal(true);
searchQuery.setStart(pageableData.getCurrentPage() * pageableData.getPageSize());
searchQuery.setCount(pageableData.getPageSize());
final SearchResult<T> searchResult = getFlexibleSearchService().search(searchQuery);
// Create the paged search result
final SearchPageData<T> result = createSearchPageData();
result.setResults(searchResult.getResult());
result.setPagination(createPagination(pageableData, searchResult));
// Note: does not set sorts
return result;
}
DefaultPagedFlexibleSearchService search
public <T> SearchPageData<T> search(final List<SortQueryData> sortQueries, final String defaultSortCode,
final Map<String, ?> queryParams, final PageableData pageableData)
{
validateParameterNotNull(sortQueries, "sortQueries cannot be null");
validateParameterNotNull(defaultSortCode, "defaultSortCode cannot be null");
validateParameterNotNull(pageableData, "pageableData cannot be null");
Assert.isTrue(!sortQueries.isEmpty(), "sortQueries must not be empty");
Assert.isTrue(pageableData.getCurrentPage() >= 0, "pageableData current page must be zero or greater");
Assert.isTrue(pageableData.getPageSize() > 0, "pageableData page size must be greater than zero");
// Work out which sort and query to use
final SortQueryData selectedSortQuery = findSortQueryData(sortQueries, pageableData.getSort(), defaultSortCode);
// Execute the query
final SearchPageData<T> searchPageData = search(selectedSortQuery.getQuery(), queryParams, pageableData);
// Specify which sort was used
searchPageData.getPagination().setSort(selectedSortQuery.getSortCode());
searchPageData.setSorts(createSorts(sortQueries, selectedSortQuery.getSortCode()));
return searchPageData;
}
DefaultCustomerAccountDao findOrdersByCustomerAndStore
public SearchPageData<OrderModel> findOrdersByCustomerAndStore(final CustomerModel customerModel, final BaseStoreModel store,
final OrderStatus[] status, final PageableData pageableData)
{
validateParameterNotNull(customerModel, "Customer must not be null");
validateParameterNotNull(store, "Store must not be null");
final Map<String, Object> queryParams = new HashMap<String, Object>();
queryParams.put("customer", customerModel);
queryParams.put("store", store);
String filterClause = StringUtils.EMPTY;
if (CollectionUtils.isNotEmpty(getFilterOrderStatusList()))
{
queryParams.put("filterStatusList", getFilterOrderStatusList());
filterClause = FILTER_ORDER_STATUS;
}
final List<SortQueryData> sortQueries;
if (ArrayUtils.isNotEmpty(status))
{
queryParams.put("statusList", Arrays.asList(status));
sortQueries = Arrays.asList(
createSortQueryData("byDate",
createQuery(FIND_ORDERS_BY_CUSTOMER_STORE_QUERY_AND_STATUS, filterClause, SORT_ORDERS_BY_DATE)),
createSortQueryData("byOrderNumber",
createQuery(FIND_ORDERS_BY_CUSTOMER_STORE_QUERY_AND_STATUS, filterClause, SORT_ORDERS_BY_CODE)));
}
else
{
sortQueries = Arrays
.asList(
createSortQueryData("byDate",
createQuery(FIND_ORDERS_BY_CUSTOMER_STORE_QUERY, filterClause, SORT_ORDERS_BY_DATE)),
createSortQueryData("byOrderNumber",
createQuery(FIND_ORDERS_BY_CUSTOMER_STORE_QUERY, filterClause, SORT_ORDERS_BY_CODE)));
}
}
return getPagedFlexibleSearchService().search(sortQueries, "byDate", queryParams, pageableData);
}
DefaultCustomerAccountService getOrderList
public SearchPageData<OrderModel> getOrderList(final CustomerModel customerModel, final BaseStoreModel store,
final OrderStatus[] status, final PageableData pageableData)
{
validateParameterNotNull(customerModel, "Customer model cannot be null");
validateParameterNotNull(store, "Store must not be null");
validateParameterNotNull(pageableData, "PageableData must not be null");
return getCustomerAccountDao().findOrdersByCustomerAndStore(customerModel, store, status, pageableData);
}
DefaultOrderFacade getPagedOrderHistoryForStatuses
public SearchPageData<OrderHistoryData> getPagedOrderHistoryForStatuses(final PageableData pageableData,
final OrderStatus... statuses)
{
final CustomerModel currentCustomer = (CustomerModel) getUserService().getCurrentUser();
final BaseStoreModel currentBaseStore = getBaseStoreService().getCurrentBaseStore();
final SearchPageData<OrderModel> orderResults = getCustomerAccountService().getOrderList(currentCustomer, currentBaseStore,
statuses, pageableData);
return convertPageData(orderResults, getOrderHistoryConverter());
}
AccountPageController orders
public String orders(@RequestParam(value = "page", defaultValue = "0") final int page,
@RequestParam(value = "show", defaultValue = "Page") final ShowMode showMode,
@RequestParam(value = "sort", required = false) final String sortCode, final Model model) throws CMSItemNotFoundException
{
// Handle paged search results
final PageableData pageableData = createPageableData(page, 5, sortCode, showMode);
final SearchPageData<OrderHistoryData> searchPageData = vinOrderFacade.getPagedOrderHistoryForStatuses(pageableData);
populateModel(model, searchPageData, showMode);
storeCmsPageInModel(model, getContentPageForLabelOrId(ORDER_HISTORY_CMS_PAGE));
setUpMetaDataForContentPage(model, getContentPageForLabelOrId(ORDER_HISTORY_CMS_PAGE));
model.addAttribute(BREADCRUMBS_ATTR, accountBreadcrumbBuilder.getBreadcrumbs("text.account.orderHistory"));
model.addAttribute(ThirdPartyConstants.SeoRobots.META_ROBOTS, ThirdPartyConstants.SeoRobots.NOINDEX_NOFOLLOW);
model.addAttribute("isASM", assistedServiceFacade.isAssistedServiceAgentLoggedIn());
return getViewForPage(model);
}
答案 0 :(得分:5)
FlexibleSearchService
此服务具有API TranslationResult translate(FlexibleSearchQuery arg0)
,您可以使用它将FlexibleSearchQuery转换为SQL查询。
例如:
private static final Logger LOG = Logger.getLogger(ExampleClass.class);
@Resource
private FlexibleSearchService flexibleSearchService
......
FlexibleSearchQuery query = new FlexibleSearchQuery(query_string);
TranslationResult result = flexibleSearchService.translate(query);
LOG.info("SQL Query : " + result.getSQLQuery());
LOG.info("SQL Query Parameter : " + result.getSQLQueryParameters());
有关详细信息,您可以在DefaultFlexibleSearchService
课程中查看其实施情况,或查看this
答案 1 :(得分:3)
如果您想测试您的flex搜索查询,请参阅SQL输出和结果,您可以从HAC执行此操作 - &gt;控制台 - &gt;灵活搜索。界面非常简单实用。
如果你想获得所有sql查询,你可以再次访问HAC - &gt;监控 - &gt;数据库 - &gt; JDBC日志记录。