簡體   English   中英

如何從querydsl獲得完全具體化的查詢

[英]How to get fully materialized query from querydsl

我正在嘗試使用querydsl為動態模式構建動態查詢。 我試圖獲得只是查詢而不必實際執行它。

到目前為止,我遇到了兩個問題: - schema.table符號不存在。 相反,我只得到表名。 - 我已經能夠得到查詢,但它將變量分開並放入'?' 相反,這是可以理解的。 但我想知道是否有某種方法可以獲得完全具體化的查詢,包括參數。

這是我當前的嘗試和結果(我使用MySQLTemplates來創建配置):

private SQLTemplates templates = new MySQLTemplates();
private Configuration configuration = new Configuration(templates); 

String table = "sometable"
Path<Object> userPath = new PathImpl<Object>(Object.class, table);
StringPath usernamePath = Expressions.stringPath(userPath, "username");
NumberPath<Long> idPath = Expressions.numberPath(Long.class, userPath, "id");
SQLQuery sqlQuery = new SQLQuery(connection, configuration)
  .from(userPath).where(idPath.eq(1l)).limit(10);
String query = sqlQuery.getSQL(usernamePath).getSQL();
return query;

而我得到的是:

select sometable.username
from sometable
where sometable.id = ?
limit ?

我想得到的是:

select sometable.username
from someschema.sometable
where sometable.id = ?
limit ?

更新:我想出了這種黑客來獲取參數實現 (不理想,並希望更好的解決方案)但仍然無法得到Schema.Table符號工作

哈克如下。 請建議更清潔的QueryDsl方法:

String query = cleanQuery(sqlQuery.getSQL(usernamePath));

private String cleanQuery(SQLBindings bindings){
    String query = bindings.getSQL();
    for (Object binding : bindings.getBindings()) {
        query = query.replaceFirst("\\?", binding.toString());
    }
    return query;
}

要啟用架構打印,請使用以下模式

SQLTemplates templates = MySQLTemplates.builder()
    .printSchema()
    .build();

以前使用過SQLTemplates子類,但是有時候構建器模式是自定義模板的官方方式http://www.querydsl.com/static/querydsl/3.3.1/reference/html/ch02s03.html#d0e904

並啟用文字的直接序列化使用

//configuration level
configuration.setUseLiterals(true);

//query level
configuration.setUseLiterals(true);

這是一個完整的例子

// configuration
SQLTemplates templates = MySQLTemplates.builder()
    .printSchema()
    .build();
Configuration configuration = new Configuration(templates);

// querying
SQLQuery sqlQuery = new SQLQuery(connection, configuration)
    .from(userPath).where(idPath.eq(1l)).limit(10);
sqlQuery.setUseLiterals(true);    
String query = sqlQuery.getSQL(usernamePath).getSQL();

如果您始終只想要SQL查詢字符串,請將setUseLiterals從查詢移動到配置。

關於Querydsl表達式的使用,建議使用此處記錄的代碼生成http://www.querydsl.com/static/querydsl/3.3.1/reference/html/ch02s03.html

它將使您的代碼類型安全,緊湊和可讀。

如果你想在沒有代碼生成的情況下嘗試Querydsl,你可以替換

Path<Object> userPath = new PathImpl<Object>(Object.class, variable);

Path<Object> userPath = new RelationalPathBase<Object>(Object.class, variable, schema, table);

使用QueryDSL時,必須為數據庫平台提供模板以構建查詢。 我看到你已經在這里這樣做了:

private SQLTemplates templates = new MySQLTemplates();
private Configuration configuration = new Configuration(templates); 

為了使模式名稱出現在生成的查詢中,我發現這樣做的唯一方法是(可能有一種更簡單的方法)是擴展模板類並顯式調用this.setPrintSchema(true); 在構造函數內部。 這是一個適用於MySql的類:

import com.mysema.query.sql.MySQLTemplates;

public class NewMySqlTemplates extends MySQLTemplates {

    public NewMySqlTemplates() {
        super('\\', false);
    }

    public NewMySqlTemplates(boolean quote) {
        super('\\', quote);
    }

    public NewMySqlTemplates(char escape, boolean quote) {
        super(escape, quote);
        this.setPrintSchema(true);
    }

}

然后簡單地使用這個NewMySqlTemplates類代替MySQLTemplates類,如下所示:

private SQLTemplates templates = new NewMySQLTemplates();
private Configuration configuration = new Configuration(templates); 

我使用PostgresTemplates工作,所以我可能在上面的NewMySqlTemplates類中有一個錯字或錯誤,但你應該能夠讓它工作。 祝好運!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM