当前位置: 首页 > 工具软件 > Querydsl > 使用案例 >

Querydsl 手动构建Predicate

夹谷腾
2023-12-01

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

}
 类似资料: