java jpa分页排序条件查询工具类

mysql查询的手写工具类

注:来源于@tianlihu讲师

在jpa分页查询时需要使用在自定义方法或者给定方法在参数中加入Pageable即可分页,但是如果参数为空则会报错。为避免这种问题·····

此篇文章涉及到,StringBuilder 、LinkedHashMap、instanceof、Sort、PageImpl、对象转map、获取泛型等java重点知识。含金量四颗星。


import ch.qos.logback.core.net.SyslogOutputStream;
import com.zhangzhi.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;

import javax.persistence.EntityManager;
import javax.persistence.Query;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.*;

/*
* StringBuilder 线程虽不安全但是快,不需要重新赋值在线程中改变值
* LinkedHashMap 使用LinkedHashMap传入的顺序不会发生变化
* */
public class BasesService<T> {
    @Autowired
    private EntityManager entityManager;

    public Page<T> findPage(Object params, Pageable pageable, Integer page, Integer pageSize) {
        page = page == null ? 0 : page;
        pageSize = pageSize == null ? 10 : pageSize;
        return findPage(params, PageRequest.of(page, pageSize));
    }
//    这个是带分页的 还可携对象的参数


    public Page<T> findPage(LinkedHashMap<String, Object> params, Integer page, Integer pageSize) {
        page = page == null ? 0 : page;
        pageSize = pageSize == null ? 10 : pageSize;
        return findPage(params, PageRequest.of(page, pageSize));
    }
//    使用时需要放到 Map  参数只需传pageNum和size


    // 第二原生  条件可使用对象转入:使用的专对象的工具方法
    public Page<T> findPage(Object params, Pageable pageable) {
        LinkedHashMap<String, Object> paramMap = entityToMap(params);
//      先调用产生数据
        List<T> list = findList(paramMap, pageable);
//      计算总数
        Long count = findCount(paramMap);
        return new PageImpl<>(list, pageable, count);
    }


    //原生!  需传入LinkedHashMap和Pageable
    public Page<T> findPage(LinkedHashMap<String, Object> params, Pageable pageable) {
        List<T> list = findList(params, pageable);
        Long count = findCount(params);
        return new PageImpl<>(list, pageable, count);
    }
//    使用时需要放到 Map  参数需要传pageable






//   产生数据的方法   参数传入查询条件、传入分页的条件
    private List<T> findList(LinkedHashMap<String, Object> params, Pageable pageable) {
        StringBuilder hql = new StringBuilder("select t from " + getEntityType().getSimpleName() + " t where 1=1");
        // 拼接条件
        makeupWhereHql(params, hql);
        // 拼接排序
        makupOrderBy(pageable, hql);
        Query query = entityManager.createQuery(hql.toString());
        // 拼接参数
        setParameters(params, query);
        query.setFirstResult((int) pageable.getOffset());
        query.setMaxResults(pageable.getPageSize());
        return query.getResultList();
    }

//    计算总条数的方法
    private Long findCount(LinkedHashMap<String, Object> params) {
        StringBuilder hql = new StringBuilder("select count(*) from " + getEntityType().getSimpleName() + " t where 1=1");
        // 拼接条件
        makeupWhereHql(params, hql);
        Query query = entityManager.createQuery(hql.toString());
        // 拼接参数
        setParameters(params, query);
        return (Long) query.getSingleResult();
    }

//  拼接排序的方法
    private void makupOrderBy(Pageable pageable, StringBuilder hql) {
        Sort sort = pageable.getSort();
        Iterator<Sort.Order> orders = sort.iterator();

        StringBuilder orderBy = new StringBuilder();
        if (orders.hasNext()) {
            Sort.Order order = orders.next();
            String property = order.getProperty();//获取他的值
            Sort.Direction direction = order.getDirection();//获取 Desc&Asc
            orderBy.append("order by " + property + " " + direction.name());
        }

        while (orders.hasNext()) {
            Sort.Order order = orders.next();
            String property = order.getProperty();
            Sort.Direction direction = order.getDirection();
            orderBy.append("," + property + " " + direction.name());
        }

        hql.append(orderBy);
    }

//    拼接条件的方法
    private void makeupWhereHql(LinkedHashMap<String, Object> params, StringBuilder hql) {
        Set<Map.Entry<String, Object>> parameters = params.entrySet();
        for (Map.Entry<String, Object> parameter : parameters) {
            Object value = parameter.getValue();
            if (value != null) {
                if (value instanceof String) {
                    hql.append(" and t." + parameter.getKey() + " like concat('%', :" + parameter.getKey() + ", '%')");
                } else {
                    hql.append(" and t." + parameter.getKey() + "=:" + parameter.getKey());
                }
            }
        }
    }
//  拼接参数的方法
    private void setParameters(LinkedHashMap<String, Object> params, Query query) {
        Set<Map.Entry<String, Object>> parameters = params.entrySet();
        for (Map.Entry<String, Object> parameter : parameters) {
            Object value = parameter.getValue();
            if (value != null) {
                query.setParameter(parameter.getKey(), value);
            }
        }
    }

//  将对象转为Map  的方法
    private static LinkedHashMap<String, Object> entityToMap(Object object) {
        LinkedHashMap<String, Object> map = new LinkedHashMap();
        for (Field field : object.getClass().getDeclaredFields()) {
            try {
                boolean flag = field.isAccessible();
                field.setAccessible(true);
                Object o = field.get(object);
                map.put(field.getName(), o);
                field.setAccessible(flag);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return map;
    }

    //这个是返回泛型的方法
    private Class<?> getEntityType() {
        Class<?> clazz = getClass();
        ParameterizedType genericSuperclass = (ParameterizedType) clazz.getGenericSuperclass();
        Type actualClassType = genericSuperclass.getActualTypeArguments()[0];
        return (Class<?>) actualClassType;
    }
}

调用

public Page<User> findOrders(String summary, Date createTime, Integer page, Integer pageSize) {
        LinkedHashMap<String, Object> params = new LinkedHashMap<>();
        params.put("summary", summary);
        params.put("createTime", createTime);
        PageRequest request = PageRequest.of(page, pageSize);
        return findPage(params, request);//调用父类的即可
 }
 

合理创造工具类中的重载,可以大幅度的提升效率.

发布了51 篇原创文章 · 获赞 172 · 访问量 2876

猜你喜欢

转载自blog.csdn.net/weixin_45519387/article/details/104066587