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 - 전체 쿼리 블록
핵심 원리 요약
- 자체 Visitor 클래스 상속
- 필요한 노드 탐색 메서드 재정의
- true 반환 시 하위 노드 탐색 지속
- stmt.accept(visitor) 호출 실행
주요 활용 영역:
- 테이블/필드/조건 정보 추출
- SQL 구조 변형 처리
- SQL 혈연 분석
- 접근 권한 검증
- SQL 보안 검사