[英]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.