querydsl-jpa动态查询

时间:2016-11-22 11:01:12

标签: 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");

}

我的输入值是字段名称(&#34;可用性&#34;,&#34; birthDate&#34;,&#34; cvId&#34; ...)以及我应该使用的字符串值表演喜欢&#39;与所有领域。

我想从字段名称开始构建查询:

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

类似的东西:

lower(cast(C.cvId as varchar(255))) like 'value'
每个字段

我可以使用querydsl-sql模块,但我想只使用jpa模块实现它。

我对创建FULL&#39;其中&#39;的机制不感兴趣。子句(我知道我必须使用BooleanBuilder,或者至少,这是我在sql版本中所做的)。

我想知道的是如何创建个人&#39;其中&#39;基于字段类型的条件。

我尝试使用PathBuilder,但似乎要使用&#34; getString或getBoolean&#34;等方法。你必须知道你想要提取的字段的类型。在我的情况下,因为我从字段名称开始,我不能使用这些方法,我不知道如何从字段名称开始识别每个字段的类型,所以我&#m; m卡住。

1 个答案:

答案 0 :(得分:1)

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

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

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

只需为每种特定类型实施处理。

这可能是丑陋的if..else或者,为了更优雅的解决方案,创建类型处理程序的Map [class-&gt; 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-&gt; Handler的永久映射,并避免查找字段类。

同样,这绝不是一个漂亮的解决方案,但应该有效。