如何从querydsl获得完全具体化的查询

我正在尝试使用querydsl为动态模式构建动态查询。 我试图获得只是查询而不必实际执行它。

到目前为止,我遇到了两个问题: – schema.table符号不存在。 相反,我只获得表名。 – 我已经能够得到查询但是它将变量分开并放入’?’ 相反,这是可以理解的。 但我想知道是否有某种方法可以获得完全具体化的查询,包括参数。

这是我当前的尝试和结果(我使用MySQLTemplates来创建配置):

private SQLTemplates templates = new MySQLTemplates(); private Configuration configuration = new Configuration(templates); String table = "sometable" Path userPath = new PathImpl(Object.class, table); StringPath usernamePath = Expressions.stringPath(userPath, "username"); NumberPath 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 userPath = new PathImpl(Object.class, variable); 

 Path userPath = new RelationalPathBase(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类中有一个错字或错误,但你应该能够让它工作。 祝你好运!