本文介绍了如何从querydsl获得完全实例化的查询的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



到目前为止,我遇到了两个问题:
- schema.table表示法缺席。相反我只得到表名。
- 我已经能够获得查询,但它分离出的变量,并放置'?',而是可以理解的。



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

  private SQLTemplates templates = new MySQLTemplates 
private配置配置= new配置(模板);

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))。
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表示法



Hack如下。请建议更干净的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子类,但由于某些时候构建器模式是自定义模板的官方方式



要启用文字的直接序列化,请使用

  //配置级别
configuration.setUseLiterals(true);

//查询级别
configuration.setUseLiterals(true);

以下是完整示例

  // configuration 
SQLTemplates templates = MySQLTemplates.builder()
.printSchema()
.build();
配置配置=新配置(模板);

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

如果您总是只想要SQL查询字符串,请将setUseLiterals从查询移动到配置。 >

关于Querydsl表达式的使用,建议使用此处记录的代码生成方法



它将使你的代码类型安全,紧凑和可读。



如果你想尝试Querydsl没有代码生成你可以替换

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

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


I am trying to use querydsl for building dynamic queries for dynamic schemas. I am trying to get just the query instead of having to actually execute it.

So far I have faced two issues:- The schema.table notation is absent. Instead I only get the table name.- I have been able to get the query but it separates out the variables and puts '?' instead which is understandable. But I am wondering if there is some way to get fully materialized query including the parameters.

Here is my current attempt and result(I am using MySQLTemplates to create the configuration):

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;

And what I get is:

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

What I wanted to get was:

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

Update: I came up with this sort of hack to get parameters materialized(Not ideal and would love better solution) But still could not get Schema.Table notation to work:

Hack follows. Please suggest cleaner QueryDsl way of doing it:

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;
}
解决方案

To enable schema printing use the following pattern

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

SQLTemplates subclasses were used before, but since some time the builder pattern is the official way to customize the templates http://www.querydsl.com/static/querydsl/3.3.1/reference/html/ch02s03.html#d0e904

And to enable direct serialization of literals use

//configuration level
configuration.setUseLiterals(true);

//query level
configuration.setUseLiterals(true);

Here is a full example

// 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();

If you always just want the SQL query string out, move setUseLiterals from query to configuration.

Concerning the usage of Querydsl expressions the usage of code generation like documented here is advised http://www.querydsl.com/static/querydsl/3.3.1/reference/html/ch02s03.html

It will make your code typesafe, compact and readable.

If you want to try Querydsl without code generation you can replace

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

with

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

这篇关于如何从querydsl获得完全实例化的查询的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-29 20:56