注釈で1行のコードを実現してQueryWrapperを構築する


効果の実現
1行のコード呼び出し効果:
QueryWrapper queryWrapper = QueryBuilder.toQueryWrapper(departmentDto);

//dtoでの注記の例
public class DepartmentDto {
 //   equals  ,    
 private Long parentId;

 //        
 @BindQuery(comparison = Comparison.CONTAINS)
 private String name;
}

パッケージの背景:
Mybatis-plusのクエリー・コンストラクタは、単一テーブルのSQLクエリーを容易に構築できます.controllerでリクエスト・パラメータを受信し、部門の検索クエリー・コードのようなクエリー条件に移行できます.
DepartmentDTO dto = …;
LambdaQueryWrapper queryWrapper = new QueryWrapper().lambda();
if(dto.getOrgId() != null){
    queryWrapper.eq(Department::getOrgId, dto.getOrgId());
}
if(dto.getName() != null){
    queryWrapper.like(Department::getName, dto.getName());
}

他のオブジェクトのクエリーコードも非常に似ています.違いは、オブジェクトが異なり、フィールドが異なることにほかならません.より簡単で一般的なソリューションを提供するにはどうすればいいですか.注釈で実現できます.
実装手順
1.注釈とマッチング方式の列挙を定義する
まず,注釈とサポートされるマッチング方式の列挙を定義する.
照合方法列挙定義:
public enum Comparison {
     EQ, //   ,  
     IN, // IN
     STARTSWITH, // xx  
     CONTAINS, //  ,  LIKE
     GT, //   
     GE, //     
     LT, //   
     LE //     
}

注記定義:(クエリーに参加するほとんどのシーンは、一致条件が「=等しい」であり、コードの量を減らすために、デフォルトでは注記なしで「等しい」です)
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface BindQuery {
     /**
      *         
      */
     Comparison comparison() default Comparison.EQ;
}

2.パッケージングツールクラス抽出非空フィールド
DTOに値があるフィールドはクエリーに参加する必要があります.dtoの空でないフィールドと値を抽出する方法を提供する必要があります.サンプルコード:
/**
 *         
 */
 private static  LinkedHashMap extractNotNullValues(DTO dto){
     LinkedHashMap resultMap = new LinkedHashMap<>();
     Class> dtoClass = dto.getClass();
     //   
     List declaredFields = BeanUtils.extractAllFields(dtoClass);
     for (Field field : declaredFields) {
         //  static,  final,transient
         boolean isStatic = Modifier.isStatic(field.getModifiers());
         boolean isFinal = Modifier.isFinal(field.getModifiers());
         boolean isTransient = Modifier.isTransient(field.getModifiers());
         if (isStatic || isFinal || isTransient) {
            continue;
         }
         //          
         field.setAccessible(true);
         Object value = field.get(dto);
         if (value != null) {
            resultMap.put(field.getName(), value);
         }
     }
     return resultMap;
}

3.注記に基づいて空でないフィールドをクエリー条件として構築
最後に、空でないフィールドの抽出を実現し、注釈マッチング方式に基づいてQueryWrapperを構築する.
/**
 *       
 */
 private static  QueryWrapper dtoToWrapper(DTO dto){
    QueryWrapper wrapper = new QueryWrapper<>();
    //   
    LinkedHashMap fieldValuesMap = extractNotNullValues(dto);
    if(V.isEmpty(fieldValuesMap)){
        return wrapper;
    }
    //   QueryWrapper
    for(Map.Entry entry : fieldValuesMap.entrySet()){
        Field field = BeanUtils.extractField(dto.getClass(), entry.getKey());
        Object value = entry.getValue();
        //         
        String columnName = getColumnName(field);
        //     
        Comparison comparison = Comparison.EQ;
        switch (comparison) {
            case EQ:
                wrapper.eq(columnName, value);
            break;
            case GT:
                wrapper.gt(columnName, value);
                break;
            ... //         
        }
    }
    return wrapper;
 }

詳細はdiboot githubに注目してください
Diboot-開発者向けの低コード開発プラットフォーム