解决PageHelper.orderby排序拓展性差,让mybatis的mapper.xml告别order by

 

文中强调了   必须使用数据库字段  这样其实是非常不灵活的  一般客户在使用我们的系统时 会在前端自由设置排序字段 都是javabean字段(在我当前项目 都是javabean字段)有可能是 多个字段排序 比如时间, 单号 等   这样非常不灵活 代码拓展性差不利于维护。点击查询 将排序字段传给后端接收。

而我们使用mybatis时 经常会用到分页工具 pageHelper (当前使用版本4.1.6,5.0版本中没有setOrderBy 这个方法) 


 而在实战开发中 我也遇到了这个问题 但是 每次一次都写死代码PageHelper.orderBy("bill_no asc,bill_date desc"),感觉非常差劲必须要数据库字段  如果设置javabean字段 直接查询报错。
突然一想,有没有办法可以通过javabean字段获取到对应的数据库字段。那么这个字段之间的映射关系怎么找 ?只有解决字段映射关系才能实现全自动排序问题。  就是个问题点了  而我们使用mybatis 时  对应的XML文件有对应的字段 映射关系 


要是能找到这个映射关系存放在程序中的哪个位置就好了,于是开始了我的debug xxxMapper.query之旅。用了 三个小时时间 搞清了设计结构 找到了存放位置。SqlSessionFactory 类的 Configuration 中就找到了 resultMap 以下是我自己封装的 分页工具类  并配上 使用方法 实战表现使用简单,推荐给大家使用 可以基于原有的代码做改进 
/**
 * 通过mybatis Configuration 找到对应的字段映射文件 统一封装分页  排序工具 2.0版本 初始化字段Map集合改用 实现
 * ApplicationListener接口的方法 初始化 columnMapping  泛型T为对应的 mapper接口  比如 SendBillDetailMapper
 * @author  bolun.zheng
 */
public class PageBaseService<T>  implements ApplicationListener<ContextRefreshedEvent> {
    @Autowired
    private SqlSessionFactory adsSqlSessionFactory ;
    public  Map<String,String> columnMapping=new ConcurrentHashMap<String,String>();

    /**
     * 获取泛型T的class
     * @return
     */
    public Class<T> getClazz() {
        Type type = getClass().getGenericSuperclass();
        Class<T> result = null;
        if (type instanceof ParameterizedType) {
            ParameterizedType pType = (ParameterizedType) type;
            result = (Class<T>) pType.getActualTypeArguments()[0];
        }
        return result;
    }

    /**
     * 初始化
     */

    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
        Configuration configuration = adsSqlSessionFactory.getConfiguration();
        ResultMap resultMap = configuration.getResultMap(getClazz().getName()+ ".BaseResultMap");
        List<ResultMapping> mappings = resultMap.getResultMappings();
        for(ResultMapping a:mappings){
            columnMapping.put(a.getProperty().toUpperCase(), a.getColumn());
        }

    }

    /**
     * 分页排序工具
     * @param pageIndex
     * @param pageSize
     * @param selector
     */
    public  void pageHelper(int pageIndex, int pageSize, E3Selector selector){
        if ( pageIndex >= 0  && pageSize >= 0) {
            PageHelper.startPage(pageIndex + 1, pageSize, false);
        }
        List<E3OrderByField> orderFields = selector.getOrderFields();
        if(CollectionUtil.isNotEmpty(orderFields)){

            StringBuffer buffer = new StringBuffer();
            for(E3OrderByField field:orderFields){

                buffer.append(columnMapping.get(field.getFieldName().toUpperCase()));
                buffer.append(" ");
                buffer.append(field.getOrder());
                buffer.append(",");
            }
            buffer.deleteCharAt(buffer.length() - 1);
            String orderBy = buffer.toString();
            if (StringUtil.isNotEmptyOrNull(orderBy)) {
                PageHelper.orderBy(orderBy);

            }
        }
    }

}
----------------------------------------------------
import java.util.Collection;
import java.util.Map;

public final class CollectionUtil {

    private CollectionUtil() {
    }

    public static boolean isEmpty(Collection<?> collection) {
        return collection == null || collection.isEmpty();
    }

    public static boolean isEmpty(Map<?, ?> map) {
        return map == null || map.isEmpty();
    }

    public static <T> boolean isEmpty(T[] t) {
        return t == null || t.length == 0;
    }

    public static boolean isNotEmpty(Collection<?> collection) {
        return !isEmpty(collection);
    }

    public static boolean isNotEmpty(Map<?, ?> map) {
        return !isEmpty(map);
    }

    public static <T> boolean isNotEmpty(T[] t) {
        return !isEmpty(t);
    }
}
-------------------------
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

/**
 * 查询器(砍掉了 过滤器等 这里只需要演示 排序所以相关代码砍去)
 * 
 *
 *
 */
public class E3Selector implements Serializable{

    private static final long serialVersionUID = -2715652697887804138L;

    private List<E3OrderByField> orderFields = new ArrayList<E3OrderByField>();
    

    public void addOrderByField(E3OrderByField orderByField) {
        this.orderFields.add(orderByField);
    }

    public boolean removeOrderByField(E3OrderByField orderByField) {
        return this.orderFields.remove(orderByField);
    }

    public List<E3OrderByField> getOrderFields() {
        return orderFields;
    }


}
------------------
/**
 * 排序字段
 *
 *
 */
public class E3OrderByField implements Serializable{

    /**
     * 
     */
    private static final long serialVersionUID = -2482596093413402138L;
    
    public static final String ASC = "ASC";
    public static final String DESC = "DESC";

    private String order = ASC;
    private String fieldName;

    public E3OrderByField(String fieldName) {
        this(fieldName, ASC);
    }

    public E3OrderByField(String fieldName, String order) {
        this.fieldName = fieldName;
        this.order = order;
    }

    public String getOrder() {
        return order;
    }

    public String getFieldName() {
        return fieldName;
    }

}

实战代码中如何使用 所有的service继承即可 


E3Selector 是接收前端传到后端的排序字段的实体类  你们在代码实际开发中根据项目中的 代码具体重新改造即可 
欢迎评论(字段原本应该是这种 数据库字段:bill_date    javabean属性: billDate  但同事没有遵循规范 大家理解我的意思就好)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值