在Spring Data中为同一QueryDSL路径创建多个别名

woe*_*ler 44 java spring querydsl spring-data spring-data-rest

我有一个扩展的通用Spring Data存储库接口QuerydslBinderCustomizer,允许我自定义查询执行.我正在尝试将内置的基本相等性测试扩展到默认存储库实现中,以便我可以使用Spring Data REST执行其他查询操作.例如:

GET /api/persons?name=Joe%20Smith  // This works by default
GET /api/persons?nameEndsWith=Smith  // This requires custom parameter binding.
Run Code Online (Sandbox Code Playgroud)

我遇到的问题是我创建的实体路径的每个别名似乎都覆盖了前面的别名绑定.

@NoRepositoryBean
public interface BaseRepository<T, ID extends Serializable>
    extends PagingAndSortingRepository<T, ID>, QueryDslPredicateExecutor<T>, QuerydslBinderCustomizer { 

    @Override
    @SuppressWarnings("unchecked")
    default void customize(QuerydslBindings bindings, EntityPath entityPath){

        Class<T> model = entityPath.getType();
        Path<T> root = entityPath.getRoot();
        for (Field field: model.getDeclaredFields()){
            if (field.isSynthetic()) continue;
            Class<?> fieldType = field.getType();
            if (fieldType.isAssignableFrom(String.class)){
                // This binding works by itself, but not after the next one is added
                bindings.bind(Expressions.stringPath(root, field.getName()))
                        .as(field.getName()  + "EndsWith")
                        .first((path, value) -> {
                            return path.endsWith(value);
                        });
                // This binding overrides the previous one
                bindings.bind(Expressions.stringPath(root, field.getName()))
                        .as(field.getName()  + "StartsWith")
                        .first((path, value) -> {
                            return path.startsWith(value);
                        });
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

是否可以为同一个字段创建多个别名?这可以通用的方式完成吗?

ape*_*lli 1

您可以通过以下方式创建绑定到 QueryDSL 的瞬态属性:

@Transient
@QueryType(PropertyType.SIMPLE)
public String getNameEndsWith() {
    // Whatever code, even return null
}
Run Code Online (Sandbox Code Playgroud)

如果您使用 QueryDSL 注释处理器,您将在元数据 Qxxx 类中看到“nameEndsWith”,因此您可以像任何持久化属性一样绑定它,但不持久化它。