Browse Source

增加注解OrderBy,对baseMapper实现的查询方法进行排序

Dervish 4 years ago
parent
commit
675bae3eba

+ 26 - 0
mybatis-plus-annotation/src/main/java/com/baomidou/mybatisplus/annotation/OrderBy.java

@@ -0,0 +1,26 @@
+package com.baomidou.mybatisplus.annotation;
+
+import java.lang.annotation.*;
+
+/**
+ * 自动排序,用法与SpringDtaJpa的OrderBy类似
+ * 在执行MybatisPlus的方法selectList(),Page()等非手写查询时自动带上.
+ * @author Dervish
+ * @date 2021-04-13
+ */
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.FIELD, ElementType.ANNOTATION_TYPE})
+public @interface OrderBy {
+
+    /**
+     * 是否倒序查询,默认是
+     */
+    boolean isDesc() default true;
+
+    /**
+     * 数字越小越靠前
+     */
+    short sort() default Short.MAX_VALUE;
+
+}

+ 6 - 6
mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/enums/SqlMethod.java

@@ -60,14 +60,14 @@ public enum SqlMethod {
      */
     SELECT_BY_ID("selectById", "根据ID 查询一条数据", "SELECT %s FROM %s WHERE %s=#{%s} %s"),
     SELECT_BY_MAP("selectByMap", "根据columnMap 查询一条数据", "<script>SELECT %s FROM %s %s\n</script>"),
-    SELECT_BATCH_BY_IDS("selectBatchIds", "根据ID集合,批量查询数据", "<script>SELECT %s FROM %s WHERE %s IN (%s) %s</script>"),
+    SELECT_BATCH_BY_IDS("selectBatchIds", "根据ID集合,批量查询数据", "<script>SELECT %s FROM %s WHERE %s IN (%s) %s </script>"),
     SELECT_ONE("selectOne", "查询满足条件一条数据", "<script>%s SELECT %s FROM %s %s %s\n</script>"),
     SELECT_COUNT("selectCount", "查询满足条件总记录数", "<script>%s SELECT COUNT(%s) FROM %s %s %s\n</script>"),
-    SELECT_LIST("selectList", "查询满足条件所有数据", "<script>%s SELECT %s FROM %s %s %s\n</script>"),
-    SELECT_PAGE("selectPage", "查询满足条件所有数据(并翻页)", "<script>%s SELECT %s FROM %s %s %s\n</script>"),
-    SELECT_MAPS("selectMaps", "查询满足条件所有数据", "<script>%s SELECT %s FROM %s %s %s\n</script>"),
-    SELECT_MAPS_PAGE("selectMapsPage", "查询满足条件所有数据(并翻页)", "<script>\n %s SELECT %s FROM %s %s %s\n</script>"),
-    SELECT_OBJS("selectObjs", "查询满足条件所有数据", "<script>%s SELECT %s FROM %s %s %s\n</script>");
+    SELECT_LIST("selectList", "查询满足条件所有数据", "<script>%s SELECT %s FROM %s %s %s %s\n</script>"),
+    SELECT_PAGE("selectPage", "查询满足条件所有数据(并翻页)", "<script>%s SELECT %s FROM %s %s %s %s\n</script>"),
+    SELECT_MAPS("selectMaps", "查询满足条件所有数据", "<script>%s SELECT %s FROM %s %s %s %s\n</script>"),
+    SELECT_MAPS_PAGE("selectMapsPage", "查询满足条件所有数据(并翻页)", "<script>\n %s SELECT %s FROM %s %s %s %s\n</script>"),
+    SELECT_OBJS("selectObjs", "查询满足条件所有数据", "<script>%s SELECT %s FROM %s %s %s %s\n</script>");
 
     private final String method;
     private final String desc;

+ 24 - 0
mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/injector/AbstractMethod.java

@@ -19,6 +19,7 @@ import com.baomidou.mybatisplus.core.enums.SqlMethod;
 import com.baomidou.mybatisplus.core.metadata.TableFieldInfo;
 import com.baomidou.mybatisplus.core.metadata.TableInfo;
 import com.baomidou.mybatisplus.core.toolkit.Constants;
+import com.baomidou.mybatisplus.core.toolkit.StringPool;
 import com.baomidou.mybatisplus.core.toolkit.sql.SqlScriptUtils;
 import org.apache.ibatis.builder.MapperBuilderAssistant;
 import org.apache.ibatis.executor.keygen.KeyGenerator;
@@ -32,6 +33,7 @@ import org.apache.ibatis.mapping.StatementType;
 import org.apache.ibatis.scripting.LanguageDriver;
 import org.apache.ibatis.session.Configuration;
 
+import java.util.Comparator;
 import java.util.List;
 import java.util.function.Function;
 import java.util.function.Predicate;
@@ -235,6 +237,28 @@ public abstract class AbstractMethod implements Constants {
         }
     }
 
+    protected String sqlOrderBy(TableInfo tableInfo){
+        //如果不存在排序字段,直接返回空
+        if(!tableInfo.isExistOrderBy()){
+            return StringPool.EMPTY;
+        }
+        List<TableFieldInfo> orderByFields = tableInfo.getOrderByFields();
+        orderByFields.sort(Comparator.comparingInt(TableFieldInfo::getOrderBySort));
+        StringBuilder sql = new StringBuilder(NEWLINE + " order by ");
+        orderByFields.forEach(
+            tableFieldInfo -> {
+                sql.append(tableFieldInfo.getColumn());
+                sql.append(" ");
+                sql.append(tableFieldInfo.getOrderByType());
+                sql.append(",");
+            }
+        );
+        //删除最后一个
+        sql.deleteCharAt(sql.length()-1);
+        //当wrapper中传递了orderBy属性,@orderBy注解失效
+        return SqlScriptUtils.convertIf(sql.toString(),String.format("%s == null or %s == null or %s == null or %s.size() == 0",WRAPPER,WRAPPER_EXPRESSION,WRAPPER_EXPRESSION_ORDER,WRAPPER_EXPRESSION_ORDER), true);
+    }
+
     /**
      * 过滤 TableFieldInfo 集合, join 成字符串
      */

+ 1 - 1
mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/injector/methods/SelectList.java

@@ -33,7 +33,7 @@ public class SelectList extends AbstractMethod {
     public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
         SqlMethod sqlMethod = SqlMethod.SELECT_LIST;
         String sql = String.format(sqlMethod.getSql(), sqlFirst(), sqlSelectColumns(tableInfo, true), tableInfo.getTableName(),
-            sqlWhereEntityWrapper(true, tableInfo), sqlComment());
+            sqlWhereEntityWrapper(true, tableInfo),sqlOrderBy(tableInfo),sqlComment());
         SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
         return this.addSelectMappedStatementForTable(mapperClass, getMethod(sqlMethod), sqlSource, tableInfo);
     }

+ 1 - 1
mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/injector/methods/SelectMaps.java

@@ -35,7 +35,7 @@ public class SelectMaps extends AbstractMethod {
     public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
         SqlMethod sqlMethod = SqlMethod.SELECT_MAPS;
         String sql = String.format(sqlMethod.getSql(), sqlFirst(), sqlSelectColumns(tableInfo, true), tableInfo.getTableName(),
-            sqlWhereEntityWrapper(true, tableInfo), sqlComment());
+            sqlWhereEntityWrapper(true, tableInfo),sqlOrderBy(tableInfo), sqlComment());
         SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
         return this.addSelectMappedStatementForOther(mapperClass, getMethod(sqlMethod), sqlSource, Map.class);
     }

+ 1 - 1
mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/injector/methods/SelectMapsPage.java

@@ -35,7 +35,7 @@ public class SelectMapsPage extends AbstractMethod {
     public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
         SqlMethod sqlMethod = SqlMethod.SELECT_MAPS_PAGE;
         String sql = String.format(sqlMethod.getSql(), sqlFirst(), sqlSelectColumns(tableInfo, true),
-            tableInfo.getTableName(), sqlWhereEntityWrapper(true, tableInfo), sqlComment());
+            tableInfo.getTableName(), sqlWhereEntityWrapper(true, tableInfo),sqlOrderBy(tableInfo), sqlComment());
         SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
         return this.addSelectMappedStatementForOther(mapperClass, getMethod(sqlMethod), sqlSource, Map.class);
     }

+ 1 - 1
mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/injector/methods/SelectPage.java

@@ -33,7 +33,7 @@ public class SelectPage extends AbstractMethod {
     public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
         SqlMethod sqlMethod = SqlMethod.SELECT_PAGE;
         String sql = String.format(sqlMethod.getSql(), sqlFirst(), sqlSelectColumns(tableInfo, true),
-            tableInfo.getTableName(), sqlWhereEntityWrapper(true, tableInfo), sqlComment());
+            tableInfo.getTableName(), sqlWhereEntityWrapper(true, tableInfo),sqlOrderBy(tableInfo), sqlComment());
         SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
         return this.addSelectMappedStatementForTable(mapperClass, getMethod(sqlMethod), sqlSource, tableInfo);
     }

+ 52 - 0
mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/metadata/TableFieldInfo.java

@@ -161,6 +161,32 @@ public class TableFieldInfo implements Constants {
      */
     private Class<? extends TypeHandler<?>> typeHandler;
 
+    /**
+     *  是否存在OrderBy注解
+     */
+    private boolean isOrderBy;
+    /**
+     * 排序类型
+     */
+    private String orderByType;
+    /**
+     * 排序顺序
+     */
+    private short orderBySort;
+
+    /**
+     * 全新的 存在 TableField 注解时使用的构造函数
+     */
+    @SuppressWarnings({"unchecked", "rawtypes"})
+    public TableFieldInfo(GlobalConfig.DbConfig dbConfig, TableInfo tableInfo, Field field, TableField tableField,
+                          Reflector reflector, boolean existTableLogic,boolean isOrderBy) {
+        this(dbConfig,tableInfo,field,tableField,reflector,existTableLogic);
+        this.isOrderBy = isOrderBy;
+        if(isOrderBy){
+            initOrderBy(field);
+        }
+    }
+
     /**
      * 全新的 存在 TableField 注解时使用的构造函数
      */
@@ -264,6 +290,17 @@ public class TableFieldInfo implements Constants {
         return fromAnnotation == FieldStrategy.DEFAULT ? fromDbConfig : fromAnnotation;
     }
 
+    /**
+     * 不存在 TableField 注解时, 使用的构造函数
+     */
+    public TableFieldInfo(GlobalConfig.DbConfig dbConfig, TableInfo tableInfo, Field field, Reflector reflector,
+                          boolean existTableLogic,boolean isOrderBy) {
+        this(dbConfig,tableInfo,field,reflector,existTableLogic);
+        this.isOrderBy = isOrderBy;
+        if(isOrderBy){
+            initOrderBy(field);
+        }
+    }
     /**
      * 不存在 TableField 注解时, 使用的构造函数
      */
@@ -312,6 +349,21 @@ public class TableFieldInfo implements Constants {
         }
     }
 
+    /**
+     * 排序初始化
+     * @param field 字段
+     */
+    private void initOrderBy(Field field){
+        OrderBy orderBy = field.getAnnotation(OrderBy.class);
+        if (null != orderBy) {
+            this.isOrderBy = true;
+            this.orderBySort = orderBy.sort();
+            this.orderByType = orderBy.isDesc()?"desc":"asc";
+        }else{
+            this.isOrderBy = false;
+        }
+    }
+
     /**
      * 逻辑删除初始化
      *

+ 19 - 4
mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/metadata/TableInfo.java

@@ -32,10 +32,7 @@ import org.apache.ibatis.mapping.ResultMap;
 import org.apache.ibatis.mapping.ResultMapping;
 import org.apache.ibatis.session.Configuration;
 
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Objects;
+import java.util.*;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.function.Predicate;
 
@@ -174,6 +171,20 @@ public class TableInfo implements Constants {
     @Setter(AccessLevel.NONE)
     private TableFieldInfo versionFieldInfo;
 
+    /**
+     * 是否存在排序
+     */
+    @Getter
+    @Setter
+    private boolean isExistOrderBy;
+
+    /**
+     * 排序列表
+     */
+    @Getter
+    @Setter
+    public List<TableFieldInfo> orderByFields = new LinkedList<>();
+
     public TableInfo(Class<?> entityType) {
         this.entityType = entityType;
     }
@@ -448,6 +459,10 @@ public class TableInfo implements Constants {
             if (i.isWithUpdateFill()) {
                 this.withUpdateFill = true;
             }
+            if(i.isOrderBy()){
+                this.isExistOrderBy = true;
+                this.orderByFields.add(i);
+            }
             if (i.isVersion()) {
                 this.withVersion = true;
                 this.versionFieldInfo = i;

+ 17 - 3
mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/metadata/TableInfoHelper.java

@@ -282,6 +282,8 @@ public class TableInfoHelper {
         boolean existTableId = isExistTableId(list);
         // 是否存在 @TableLogic 注解
         boolean existTableLogic = isExistTableLogic(list);
+        // 是否存在 @OrderBy 注解
+        boolean existOrderBy = isExistOrderBy(list);
 
         List<TableFieldInfo> fieldList = new ArrayList<>(list.size());
         for (Field field : list) {
@@ -311,12 +313,12 @@ public class TableInfoHelper {
 
             /* 有 @TableField 注解的字段初始化 */
             if (tableField != null) {
-                fieldList.add(new TableFieldInfo(dbConfig, tableInfo, field, tableField, reflector, existTableLogic));
+                fieldList.add(new TableFieldInfo(dbConfig, tableInfo, field, tableField, reflector, existTableLogic,existOrderBy));
                 continue;
             }
 
-            /* 无 @TableField 注解的字段初始化 */
-            fieldList.add(new TableFieldInfo(dbConfig, tableInfo, field, reflector, existTableLogic));
+            /* 无 @TableField  注解的字段初始化 */
+            fieldList.add(new TableFieldInfo(dbConfig, tableInfo, field, reflector, existTableLogic,existOrderBy));
         }
 
         /* 字段列表 */
@@ -352,6 +354,18 @@ public class TableInfoHelper {
         return list.stream().anyMatch(field -> field.isAnnotationPresent(TableLogic.class));
     }
 
+    /**
+     * <p>
+     * 判断排序注解是否存在
+     * </p>
+     *
+     * @param list 字段列表
+     * @return true 为存在 @TableId 注解;
+     */
+    public static boolean isExistOrderBy(List<Field> list){
+        return list.stream().anyMatch(field -> field.isAnnotationPresent(OrderBy.class));
+    }
+
     /**
      * <p>
      * 主键属性初始化

+ 8 - 0
mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/toolkit/Constants.java

@@ -96,6 +96,14 @@ public interface Constants extends StringPool, Serializable {
      * wrapper 类的属性 entity 带后缀 ==> .
      */
     String WRAPPER_ENTITY_DOT = WRAPPER_DOT + "entity" + DOT;
+    /**
+     * wrapper 类的属性 expression
+     */
+    String WRAPPER_EXPRESSION = WRAPPER_DOT + "expression";
+    /**
+     * wrapper 类的属性 expression 下级属性 order
+     */
+    String WRAPPER_EXPRESSION_ORDER = WRAPPER_EXPRESSION + DOT + "orderBy";
     /**
      * UpdateWrapper 类的属性 sqlSet
      */