文中强调了 必须使用数据库字段 这样其实是非常不灵活的 一般客户在使用我们的系统时 会在前端自由设置排序字段 都是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
@Autowired
private SqlSessionFactory adsSqlSessionFactory ;
public Map
/**
* 获取泛型T的class
* @return
*/
public Class
Type type = getClass().getGenericSuperclass();
Class
if (type instanceof ParameterizedType) {
ParameterizedType pType = (ParameterizedType) type;
result = (Class
}
return result;
}
/**
* 初始化
*/
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
Configuration configuration = adsSqlSessionFactory.getConfiguration();
ResultMap resultMap = configuration.getResultMap(getClazz().getName()+ ".BaseResultMap");
List
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
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
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
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
public void addOrderByField(E3OrderByField orderByField) {
this.orderFields.add(orderByField);
}
public boolean removeOrderByField(E3OrderByField orderByField) {
return this.orderFields.remove(orderByField);
}
public List
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 但同事没有遵循规范 大家理解我的意思就好)