Spring Data JPA项目实战(下)

一 项目说明

结合Specification和自定义Repository实现来定制一个自动模糊查询。即对于任意实体类型进行查询,对象里有几个值就查几个值,当值为字符型时,就通过like查询,其余的类型使用自动等于查询,没有值就查询全部。

二 实战

1 定义Specification

package com.wisely.specs;

import static com.google.common.collect.Iterables.toArray;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.persistence.metamodel.Attribute;
import javax.persistence.metamodel.EntityType;
import javax.persistence.metamodel.SingularAttribute;

import org.springframework.data.jpa.domain.Specification;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.StringUtils;

public class CustomerSpecs {
    //定义一个返回值为Specification的方法byAuto,这里使用的是泛型T,所以这个Specification是可以用于任意的实体类
    //它接受的参数是entityManager和当前包含值作为查询条件的实体类对象
    public static <T> Specification<T> byAuto(final EntityManager entityManager, final T example) { 

        final Class<T> type = (Class<T>) example.getClass();//当前实体类对象的类型

        return new Specification<T>() {

            @Override
            public Predicate toPredicate(Root<T> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                List<Predicate> predicates = new ArrayList<>(); //新建Predicate列表存储构造的查询条件
                //获得实体类的EntityType,可以从中获得实体类的属性
                EntityType<T> entity = entityManager.getMetamodel().entity(type);
                
                for (Attribute<T, ?> attr : entity.getDeclaredAttributes()) {//对实体类的所有属性做循环
                    Object attrValue = getValue(example, attr); //获得实体类对象某个属性的值
                    if (attrValue != null) {
                        if (attr.getJavaType() == String.class) { //当前属性值为字符串的时候
                            if (!StringUtils.isEmpty(attrValue)) { //字符串不为空
                                predicates.add(cb.like(root.get(attribute(entity, attr.getName(), String.class)),
                                        pattern((String) attrValue))); //构造当前属性like属性值查询条件,并添加到条件列表中
         
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值