Java querydsl jpa动态查询

Java querydsl jpa动态查询,java,jpql,querydsl,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("birt

假设我有一个生成的实体,如下所示:

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");

}
对于每个字段

我可以使用GN querydsl sql模块来实现这一点,但我只想使用jpa模块来实现

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

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


我尝试使用PathBuilder,但似乎要使用“getString或getBoolean”之类的方法,就必须知道要提取的字段的类型。在我的例子中,因为我只是从字段名开始,所以我不能使用这些方法,也不知道如何从字段名开始识别每个字段的类型,所以我被卡住了。

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

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

您肯定可以从字段名中找到字段类(使用反射或通过维护随每个字段更新的成员映射)

只需为每个特定类型实现处理

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

伪代码:

//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的永久映射,并避免查找field类


再次强调,这绝不是一个很好的解决方案,但应该会起作用。

感谢您的回答,但我希望避免“硬编码”任何类型的映射。我觉得我应该可以做我想做的事,没有这个…:/我不会称之为“硬编码”。DatePathBase的集合非常有限,并且很少会随着库的升级而改变(如果有的话)。此外,如果在处理字段中升级后不使用新类型,则不需要更新任何内容,基本上这是一次性工作。您没有将字段名称映射到处理程序,而是映射字段类型,因此它更像是一种“框架”,而不是硬编码处理,一个精简的抽象层到API。您是对的,内省绝对是正确的方法。我真傻,没想到:)谢谢。
//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());
...