SQLASTVisitorAdapter 사용법 및 활용 사례

SQLASTVisitorAdapter 개념 정의

SQLASTVisitorAdapter는 SQL 문 구조를 탐색하는 데 사용되는 추상 클래스로, 모든 노드 탐색 메서드를 기본적으로 구현하고 있습니다.

핵심 기능:

  • SQLASTVisitor 인터페이스를 구현한 상위 클래스
  • 모든 visit 메서드를 공백으로 구현한 어댑터 역할 수행
  • 필요한 노드만 재정의하여 사용 가능

기초 사용 예제

목표: SQL 문에서 모든 테이블명과 별칭 추출


import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.sql.visitor.SQLASTVisitorAdapter;
import com.alibaba.druid.util.JdbcConstants;

public class TableInfoPrinter extends SQLASTVisitorAdapter {
    @Override
    public boolean visit(SQLExprTableSource tableSource) {
        System.out.println("테이블명: " + tableSource.getExpr().toString());
        System.out.println("별칭: " + tableSource.getAlias());
        return true;
    }

    public static void main(String[] args) {
        String sql = "SELECT e.name FROM emp e JOIN dept d ON e.dept_id = d.id";
        SQLStatement stmt = SQLUtils.parseSingleStatement(sql, JdbcConstants.MYSQL);
        stmt.accept(new TableInfoPrinter());
    }
}

주요 활용 시나리오

1. SELECT 필드 추출


@Override
public boolean visit(SQLSelectItem selectItem) {
    System.out.println("선택 필드: " + selectItem.toString());
    return true;
}

2. WHERE 조건 분석


@Override
public boolean visit(SQLBinaryOpExpr binaryExpr) {
    System.out.println("조건문: " + binaryExpr.toString());
    return true;
}

3. 함수 호출 추출


@Override
public boolean visit(SQLMethodInvokeExpr methodCall) {
    System.out.println("함수명: " + methodCall.getMethodName());
    return true;
}

통합 분석용 Visitor


import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.sql.visitor.SQLASTVisitorAdapter;
import java.util.*;

public class SQLParserVisitor extends SQLASTVisitorAdapter {
    public Set<String> tableNames = new HashSet<>();
    public Set<String> fieldNames = new HashSet<>();
    public List<String> conditionList = new ArrayList<>();

    @Override
    public boolean visit(SQLExprTableSource tableSource) {
        tableNames.add(tableSource.getExpr().toString());
        return true;
    }

    @Override
    public boolean visit(SQLSelectItem selectItem) {
        fieldNames.add(selectItem.toString());
        return true;
    }

    @Override
    public boolean visit(SQLBinaryOpExpr binaryExpr) {
        conditionList.add(binaryExpr.toString());
        return true;
    }
}

SQL 변형 처리

테이블 별칭 자동 추가


@Override
public boolean visit(SQLExprTableSource tableSource) {
    tableSource.setAlias("tbl");
    return true;
}

WHERE 조건 추가


@Override
public boolean visit(SQLSelectQueryBlock queryBlock) {
    SQLExpr where = queryBlock.getWhere();
    SQLExpr newCondition = SQLUtils.toSQLExpr("status=2", JdbcConstants.MYSQL);

    if (where == null) {
        queryBlock.setWhere(newCondition);
    } else {
        queryBlock.setWhere(new SQLBinaryOpExpr(where, SQLBinaryOperator.AND, newCondition));
    }
    return true;
}

필수 visit 메서드 목록

  • SQLExprTableSource - 테이블 노드
  • SQLJoinTableSource - JOIN 노드
  • SQLSubqueryTableSource - 서브쿼리 노드
  • SQLSelectItem - 선택 필드 노드
  • SQLWhereClause - WHERE 조건 노드
  • SQLBinaryOpExpr - 비교 조건 노드
  • SQLMethodInvokeExpr - 함수 호출 노드
  • SQLOrderBy - ORDER BY 노드
  • SQLLimit - LIMIT 노드
  • SQLSelectQueryBlock - 전체 쿼리 블록

핵심 원리 요약

  1. 자체 Visitor 클래스 상속
  2. 필요한 노드 탐색 메서드 재정의
  3. true 반환 시 하위 노드 탐색 지속
  4. stmt.accept(visitor) 호출 실행

주요 활용 영역:

  • 테이블/필드/조건 정보 추출
  • SQL 구조 변형 처리
  • SQL 혈연 분석
  • 접근 권한 검증
  • SQL 보안 검사

태그: Druid sql-parser visitor-pattern sql-ast query-analysis

7월 14일 18:08에 게시됨