QuerydslBindings:一组字段信息和字段信息的查询方式的绑定
new QuerydslBindings() {
{
bind(QUser.user.address.city).first((path, value) -> path.like(value.toString()));
bind(String.class).first((path, value) -> path.like(value.toString()));
}
}
QuerydslBindingsFactory:管理系统中所有的QuerydslBindings
ConversionService:Spring Core提供的对象转换服务接口,默认使用的是Spring MVC模块提供的转换服务工厂
@Autowired @Qualifier("mvcConversionService") ObjectFactory<ConversionService> conversionService;
QuerydslPredicateBuilder:Predicate构建器。
package com.fengxin58.beethoven.querydsl.support;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.support.DefaultConversionService;
import org.springframework.data.querydsl.SimpleEntityPathResolver;
import org.springframework.data.querydsl.binding.QuerydslBinderCustomizer;
import org.springframework.data.querydsl.binding.QuerydslBindings;
import org.springframework.data.querydsl.binding.QuerydslBindingsFactory;
import org.springframework.data.querydsl.binding.QuerydslPredicateBuilder;
import org.springframework.data.querydsl.binding.SingleValueBinding;
import org.springframework.data.util.ClassTypeInformation;
import org.springframework.data.util.TypeInformation;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.util.ObjectUtils;
import com.fengxin58.beethoven.domain.model.machine.MachineCpu;
import com.fengxin58.beethoven.domain.model.machine.QMachineCpu;
import com.querydsl.core.types.Predicate;
import com.querydsl.core.types.dsl.StringPath;
public class QuerydslPredicateResolver {
private final QuerydslBindingsFactory bindingsFactory;
private final QuerydslPredicateBuilder predicateBuilder;
/**
* Creates a new {@link QuerydslPredicateResolver} using the given
* {@link QuerydslBindingsFactory}.
*
* @param factory
*/
public QuerydslPredicateResolver(QuerydslBindingsFactory factory) {
this(factory, null);
}
/**
* Creates a new {@link QuerydslPredicateResolver} using the given
* {@link ConversionService}.
*
* @param factory
* @param conversionService
* defaults to {@link DefaultConversionService} if
* {@literal null}.
*/
public QuerydslPredicateResolver(QuerydslBindingsFactory factory, ConversionService conversionService) {
this.bindingsFactory = factory;
this.predicateBuilder = new QuerydslPredicateBuilder(
conversionService == null ? new DefaultConversionService() : conversionService,
factory.getEntityPathResolver());
}
/**
* resolve and build {@link Predicate}.
*
* @param root
* root class
* @param customizerClass
* the {@link QuerydslBinderCustomizer} class instance
* @param parameterMap
* parameter map , value can be string or string[] object
* @return
* @throws Exception
*/
public Predicate resolve(Class<?> root, Class<? extends QuerydslBinderCustomizer<?>> customizerClass,
Map<String, Object> parameterMap) throws Exception {
MultiValueMap<String, String> parameters = new LinkedMultiValueMap<String, String>();
for (Entry<String, ?> entry : parameterMap.entrySet()) {
Object object = entry.getValue();
if (object instanceof String) {
parameters.put(entry.getKey(), Arrays.asList((String) entry.getValue()));
} else if (object instanceof String[]) {
parameters.put(entry.getKey(), Arrays.asList((String[]) entry.getValue()));
}
}
TypeInformation<?> domainType = extractTypeInfo(root).getActualType();
if (ObjectUtils.isEmpty(domainType)) {
throw new Exception("unable to find domainType");
}
Class<? extends QuerydslBinderCustomizer<?>> customizer = customizerClass;
QuerydslBindings bindings = bindingsFactory.createBindingsFor(customizer, domainType);
return predicateBuilder.getPredicate(domainType, parameters, bindings);
}
/**
*
* @param root
* @return
*/
private static TypeInformation<?> extractTypeInfo(Class<?> root) {
if (root != null && !Object.class.equals(root)) {
return ClassTypeInformation.from(root);
}
return null;
}
private static class MachineCpuRepository implements QuerydslBinderCustomizer<QMachineCpu> {
@Override
public void customize(QuerydslBindings bindings, QMachineCpu computerCpu) {
bindings.bind(computerCpu.type).first(new SingleValueBinding<StringPath, String>() {
@Override
public Predicate bind(StringPath path, String value) {
return path.eq(value);
}
});
// bindings.including(paths);
bindings.excluding(computerCpu.createTime);
}
}
public static void main(String[] args) throws Exception {
QuerydslBindingsFactory querydslBindingsFactory = new QuerydslBindingsFactory(
SimpleEntityPathResolver.INSTANCE);
Map<String, Object> paramatersMap = new HashMap<>();
paramatersMap.put("type", "TinkPad");
QuerydslPredicateResolver resolver = new QuerydslPredicateResolver(querydslBindingsFactory);
Predicate predicate = resolver.resolve(MachineCpu.class, MachineCpuRepository.class, paramatersMap);
System.out.println(predicate);
}
}
package com.fengxin58.beethoven.querydsl.support;
import java.util.HashMap;
import java.util.Map;
import org.springframework.data.querydsl.SimpleEntityPathResolver;
import org.springframework.data.querydsl.binding.QuerydslBinderCustomizer;
import org.springframework.data.querydsl.binding.QuerydslBindings;
import org.springframework.data.querydsl.binding.QuerydslBindingsFactory;
import org.springframework.data.querydsl.binding.SingleValueBinding;
import com.fengxin58.beethoven.domain.model.machine.MachineCpu;
import com.fengxin58.beethoven.domain.model.machine.QMachineCpu;
import com.querydsl.core.types.Predicate;
import com.querydsl.core.types.dsl.StringPath;
public class QuerydslPredicateResolverTest {
private static class MachineCpuRepository implements QuerydslBinderCustomizer<QMachineCpu> {
@Override
public void customize(QuerydslBindings bindings, QMachineCpu computerCpu) {
bindings.bind(computerCpu.type).first(new SingleValueBinding<StringPath, String>() {
@Override
public Predicate bind(StringPath path, String value) {
return path.eq(value);
}
});
// bindings.including(paths);
bindings.excluding(computerCpu.createTime);
}
}
public static void main(String[] args) throws Exception {
QuerydslBindingsFactory querydslBindingsFactory = new QuerydslBindingsFactory(
SimpleEntityPathResolver.INSTANCE);
Map<String, Object> paramatersMap = new HashMap<>();
paramatersMap.put("type", "TinkPad");
QuerydslPredicateResolver resolver = new QuerydslPredicateResolver(querydslBindingsFactory);
Predicate predicate = resolver.resolve(MachineCpu.class, MachineCpuRepository.class, paramatersMap);
System.out.println(predicate);
}
}