java - querydsl-jpa动态查询

标签 java jpql querydsl

假设我有一个像这样生成的实体:

public class QCandidate extends EntityPathBase<Candidate> {

public final com.avisto.candisearch.persistance.model.enums.QAvailabilityEnum availability;

public final DatePath<java.util.Date> birthDate = createDate("birthDate", java.util.Date.class);

public final NumberPath<Long> cvId= createNumber("cvId", Long.class);

public final StringPath city = createString("city");

}

我的输入值是字段名称(“availability”、“birthDate”、“cvId”...)和一个字符串值,我应该使用它对所有字段执行“like”。

我想从以下字段名称开始构建一个查询:

  • 将日期和数字转换为字符串并将其小写
  • 如果字段是 EntityPathBase(如可用性),则提取 id,然后再次转换为小写字符串

类似于:

lower(cast(C.cvId as varchar(255))) like 'value'

对于每个字段。

我可以使用 querydsl-sql 模块来完成此操作,但我想仅使用 jpa 模块来实现它。

我对创建完整“where”子句的机制不感兴趣(我知道我必须使用 BooleanBuilder,或者至少,这是我在 sql 版本中所做的)。

我想知道的是如何根据字段类型创建单独的“where”条件。

我正在尝试使用 PathBuilder,但似乎要使用“getString 或 getBoolean”等方法,您已经必须知道要提取的字段的类型。就我而言,由于我只是从字段名称开始,所以我无法使用这些方法,而且我不知道如何从字段名称开始识别每个字段的类型,所以我陷入了困境。

最佳答案

可能有点难看,但可行的建议。

请注意,PathBuilder 接受的字段类型数量非常有限。

您绝对可以从字段名称找到字段类(使用反射或通过维护每个字段更新的成员映射)。

只需实现对每种特定类型的处理即可。

这可能是一堆丑陋的 if..else ,或者,为了更优雅的解决方案,创建类型处理程序 [class->handler] 的映射,每个处理程序实现接口(interface)方法来处理特定类型。

伪代码:

//building query
for each field
  Class fieldClass = findFieldClas(.., field) //use reflection or map
  PathHandler handler = handlers.get(fieldClass)
  handler.process( ...)

//type handler interface
public interface Handler{
  public xx process(? extends DataPathBase);
}

//specific type handler implementation
public class BooleanHandler implements Handler{
  public xx process(? extends DataPathBase path){
    BooleanPath bPath = (BooleanPath)path;
    ...
}

//intitialize handlers map singleton or a factory in advance    
handlers.put(BooleanPath.class, new BooleanHandler());
...

请注意,如果您有很多类,这是一个通用解决方案。如果您只有一个特定的类,则可以创建一个 fieldName->Handler 的永久映射,并避免查找字段类。

再说一遍,这绝不是一个漂亮的解决方案,但应该可行。

关于java - querydsl-jpa动态查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40740136/

相关文章:

java - QueryDSL - 如何加入子查询联合

java - 如何获取 Map<Long, Date> 中的最新日期?

拖动手势 Activity 时未引发 JavaFX KeyEvent

java - Android MVVM RecyclerView ClickListener Kotlin 到 Java 转换

java - JPQL 和实体数据

java - QueryDSL - 按计数排序作为别名

java - 哈希表Java插入

java - 如何覆盖 Spring Data CrudRepository 上的删除方法?

java - JPA ManyToOne Cascade 使用 JPQL 进行更新

querydsl - 如何将涉及连接的 JPAQuery 对象转换为谓词?