繁体   English   中英

如何在没有域类的情况下在querydsl中构造查询

[英]How to construct query in querydsl without domain classes

在寻找java库以数据库无关的方式构建查询时,我遇到了许多包括iciql,querydsl,jooq,joist,hibernate等。

我想要一些不需要配置文件的东西,可以使用动态模式。 对于我的应用程序,我在运行时了解了数据库和模式,因此我不会为模式提供任何配置文件或域类。

这似乎是querydsl的核心目标之一,但是通过querydsl的文档我看到很多用于使用域类构建动态查询的示例但是我没有遇到任何解释如何使用仅仅构建这样的数据库不可知查询我有关于架构的动态信息。

Jooq提供此类功能(请参阅: http//www.jooq.org/doc/3.2/manual/getting-started/use-cases/jooq-as-a-standalone-sql-builder/ )但如果​​有限制性许可,我想将我的重点扩展到Oracle或MS SQL(我可能不喜欢但需要支持)。

有querydsl经验的人能告诉我querydsl是否可以做到这一点,如果是的话,怎么做。

如果有人知道任何其他可以满足我的要求,那将非常感激。

一个非常简单的SQL查询,例如:

@Transactional
public User findById(Long id) {
    return new SQLQuery(getConnection(), getConfiguration())
      .from(user)
      .where(user.id.eq(id))
      .singleResult(user);
}

...可以像这样动态创建(不添加任何糖):

@Transactional
public User findById(Long id) {
    Path<Object> userPath = new PathImpl<Object>(Object.class, "user");
    NumberPath<Long> idPath = Expressions.numberPath(Long.class, userPath, "id");
    StringPath usernamePath = Expressions.stringPath(userPath, "username");
    Tuple tuple = new SQLQuery(getConnection(), getConfiguration())
      .from(userPath)
      .where(idPath.eq(id))
      .singleResult(idPath, usernamePath);
    return new User(tuple.get(idPath), tuple.get(usernamePath));
}

以下是使用PathBuilder的ponzao解决方案的一小部分变体

@Transactional
public User findById(Long id) {        
    PathBuilder<Object> userPath = new PathBuilder<Object>(Object.class, "user");
    NumberPath<Long> idPath = userPath.getNumber("id", Long.class);
    StringPath usernamePath = userPath.getString("username");
    Tuple tuple = new SQLQuery(getConnection(), getConfiguration())
      .from(userPath)
      .where(idPath.eq(id))
      .singleResult(idPath, usernamePath);
    return new User(tuple.get(idPath), tuple.get(usernamePath));
}

更新:Timo通过向我展示如何执行我想要的操作而无需替换SQLQuery类,从而使我的原始响应无效。 以下是他的评论:

query.getSQL(field1, field2, ... fieldN), getSQL is consistent with the
other methods which also take the projection arguments at last

我删除了不必要的课程。 下面是一个使用SQLQuery直接获取SQL字符串而不执行查询的示例(例如,不使用list方法):

SQLQuery rquery = new SQLQuery(connection , dialect);

// Use getSQL with projections
rquery.from(qtable)
    .where(qtable.qfield1.eq("somevalue"));

SQLBindings bindings = rquery.getSQL(qtable.qfield1, qtable.qfield2);

// Get the SQL string from the SQLBindings
System.out.println(bindings.getSql());

// Get the SQL parameters from the SQLBindings for the parameterized query
System.out.println(bindings.getBindings());

此响应回答了如何使用QueryDSL构建完整的SQL查询而不实际执行查询。 它没有解决您对“动态模式”和“没有域对象”的额外要求......

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM