You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

QueryDSL生成原生Oracle查询格式不符,如何获取预期物化查询

How to Generate Exact Native Oracle Query with QueryDSL (Matching Expected Table/Column Names)

Let's break down the issue and fix it step by step. You're trying to generate a native Oracle query that matches your expected format, but QueryDSL is outputting camelCase table/column names instead of the uppercase underscore format you need. Plus, the table alias and account number value don't match your target query.

Expected vs. Generated Query

Expected Query:

select test.TEST_KEY from TEST_TABLE test where test.TEST_CODE = 'TEST_01' and test.TEST_ACCOUNT_NUMBER = '001' and test.POSTED_UTC_DATE between timestamp '2020-06-19 23:59:59' and timestamp '2020-06-19 23:59:59'

Current Generated Query:

select testTable.testKey from testTable where testTable.testCode = 'TEST_01' and testTable.testAccountNumber = '0000124001' and testTable.postedUtcDate between timestamp '2020-06-19 23:59:59' and timestamp '2020-06-19 23:59:59'

Your Current Implementation

public String getTestResults(DataDto dataDto) {
    SQLTemplates templates= OracleTemplates.builder().printSchema().build();
    Configuration configuration=new Configuration(templates);
    configuration.setUseLiterals(true);
    PathBuilder<?> entityPath = new PathBuilder<>(getEntityClass(), getEntityName());
    SQLQuery<Object> sqlQuery= (SQLQuery<Object>) new SQLQuery(configuration)
            .select(entityPath.getString(getColumnMap().get("TEST_KEY")))
            .from(entityPath)
            .where(buildCondition(dataDto).build());
    sqlQuery.setUseLiterals(true);
    String query=sqlQuery.getSQL().getSQL();
    return query;
}

You mentioned you've checked QueryDSL docs and references but haven't resolved this—let's fix each discrepancy one by one.


Fixes to Generate the Exact Query

1. Force Uppercase Identifiers for Oracle

Oracle treats unquoted identifiers as uppercase, so we need to configure QueryDSL to output identifiers in uppercase underscore format instead of camelCase. Modify your SQLTemplates setup:

// Use Oracle's default template which handles uppercase correctly
SQLTemplates templates = OracleTemplates.DEFAULT;
// Alternatively, for custom settings:
// SQLTemplates templates = OracleTemplates.builder()
//         .printSchema()
//         .quoteIdentifiers(false) // Disable quoting so Oracle uses uppercase
//         .build();

2. Set the Correct Table Alias

Add the as() method to your from() clause to use the test alias you need:

.from(entityPath.as("test"))

3. Map CamelCase Properties to Uppercase Underscore Columns

Since you're using PathBuilder, add a custom naming strategy to convert camelCase property names to the uppercase underscore column names your database uses:

import org.apache.commons.lang3.StringUtils;
import com.querydsl.core.DefaultNamingStrategy;

configuration.setNamingStrategy(new DefaultNamingStrategy() {
    @Override
    public String getColumnName(String property) {
        // Convert camelCase to UPPERCASE_UNDERSCORE format
        String[] camelParts = StringUtils.splitByCharacterTypeCamelCase(property);
        return StringUtils.join(camelParts, "_").toUpperCase();
    }
});

Now, when you reference entityPath.getString("testKey"), it will automatically map to TEST_KEY in the generated SQL.

4. Fix the Account Number Value

Double-check your buildCondition(dataDto) method—currently it's passing 0000124001 instead of 001. Ensure the value pulled from dataDto is the correct 001 string (verify there's no unintended formatting or data conversion happening).


Adjusted Full Code Example

import org.apache.commons.lang3.StringUtils;
import com.querydsl.core.DefaultNamingStrategy;
import com.querydsl.core.configuration.Configuration;
import com.querydsl.core.sql.OracleTemplates;
import com.querydsl.core.sql.SQLQuery;
import com.querydsl.core.sql.SQLTemplates;
import com.querydsl.core.types.PathBuilder;

public String getTestResults(DataDto dataDto) {
    // Configure Oracle-specific templates for uppercase identifiers
    SQLTemplates templates = OracleTemplates.DEFAULT;
    Configuration configuration = new Configuration(templates);
    configuration.setUseLiterals(true);

    // Naming strategy to convert camelCase properties to uppercase underscore columns
    configuration.setNamingStrategy(new DefaultNamingStrategy() {
        @Override
        public String getColumnName(String property) {
            String[] camelParts = StringUtils.splitByCharacterTypeCamelCase(property);
            return StringUtils.join(camelParts, "_").toUpperCase();
        }
    });

    PathBuilder<?> entityPath = new PathBuilder<>(getEntityClass(), getEntityName());
    SQLQuery<Object> sqlQuery = (SQLQuery<Object>) new SQLQuery(configuration)
            .select(entityPath.getString("testKey")) // Maps to TEST_KEY via naming strategy
            .from(entityPath.as("test")) // Set table alias to "test"
            .where(buildCondition(dataDto).build());

    sqlQuery.setUseLiterals(true);
    return sqlQuery.getSQL().getSQL();
}

If you're not already using QueryDSL's Annotation Processing Tool (APT) to generate Q classes, you should start. These classes auto-map your database tables/columns correctly, eliminating manual PathBuilder setup. For example:

// Assuming QTestTable is generated by APT
QTestTable test = QTestTable.testTable.as("test");
SQLQuery<Object> sqlQuery = new SQLQuery(configuration)
        .select(test.testKey)
        .from(test)
        .where(test.testCode.eq("TEST_01")
                .and(test.testAccountNumber.eq("001"))
                .and(test.postedUtcDate.between(
                        Timestamp.valueOf("2020-06-19 23:59:59"),
                        Timestamp.valueOf("2020-06-19 23:59:59"))));

This approach is more maintainable and less error-prone than manual PathBuilder configuration.

内容的提问来源于stack exchange,提问作者Himanshu Upadhyay

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 15:12:54