Chuyển tới nội dung chính

Phân tích SQL

Phân tích câu lệnh SQL (INSERT/UPDATE/DELETE/SELECT ... FOR UPDATE) thành các recognizer theo loại database, kèm SPI cho table meta cache và escape identifier. Dùng khi cần đọc thông tin bảng/cột/điều kiện từ SQL thô để audit, undo, revision hoặc xử lý datasource.

Khi nào sử dụng

  • Cần parse SQL do người dùng/ứng dụng sinh ra để biết bảng, cột, điều kiện WHERE, ORDER BY, LIMIT mà không tự viết parser.
  • Cần metadata bảng (cột, index, khoá chính) phục vụ sinh câu SQL đảo ngược hoặc audit.
  • Cần escape/unescape identifier theo từng database (tên cột là keyword như order).
  • Đang dùng govex-cloud-datasource hoặc các dependency phía trên (audit, transaction, revision) — đây là tầng parse mà chúng dựa vào.

Cài đặt

<dependency>
<groupId>vn.govex.cloud</groupId>
<artifactId>govex-cloud-sqlparser</artifactId>
</dependency>

Version do BOM quản lý — xem Cài đặt.

Cấu hình

Cấu hình duy nhất được đọc chung qua ConfigurationFactory:

PropertyMô tảMặc định
govex.audit.ignore-tablesDanh sách bảng bỏ qua khi tạo recognizer; hỗ trợ tên kèm schema (schema.table).

Các SPI cần implementation khi dùng ngoài govex-cloud-datasource:

  • TableMetaCache — cache metadata theo datasource.
  • EscapeHandler — escape/unescape identifier theo db type.

Sử dụng

Parse một câu SQL và duyệt kết quả:

List<SQLRecognizer> recognizers = SQLVisitorFactory.get(
"UPDATE users SET name = ? WHERE id = ?", JdbcConstants.MYSQL);

for (SQLRecognizer recognizer : recognizers) {
SQLType type = recognizer.getSQLType();
String table = recognizer.getTableName();

if (recognizer instanceof WhereRecognizer whereRecognizer) {
String where = whereRecognizer.getWhereCondition();
String limit = whereRecognizer.getLimitCondition();
String orderBy = whereRecognizer.getOrderByCondition();
}

if (recognizer instanceof SQLUpdateRecognizer updateRecognizer) {
List<String> columns = updateRecognizer.getUpdateColumns();
List<Object> values = updateRecognizer.getUpdateValues();
}
}

Suy ra db type từ JDBC URL và escape tên cột:

DbTypeParser dbTypeParser = new DruidDbTypeParserImpl();
String dbType = dbTypeParser.parseFromJdbcUrl("jdbc:mysql://localhost:3306/app");

EscapeHandler handler = EscapeHandlerFactory.getEscapeHandler(dbType);
String escaped = handler.addColNameEscape("order");

Khi có metadata bảng, TableMetaCache.getTableMeta(connection, tableName, resourceId) trả TableMeta để truyền vào các hàm kiểm tra keyword cần ngữ cảnh bảng.

Lưu ý

  • Dependency phụ thuộc govex-cloud-commoncom.alibaba:druid (SQL parser/AST).
  • EscapeHandlerTableMetaCache không có implementation trong dependency này — govex-cloud-datasource cung cấp implementation mặc định; dùng độc lập cần tự đăng ký SPI (META-INF/services) hoặc cắm implementation.
  • SQLVisitorFactory.get trả về danh sách recognizer cho câu SQL; multi-statement chỉ hỗ trợ cùng loại UPDATE hoặc DELETE, trường hợp khác có thể ném UnsupportedOperationException.
  • SQLRecognizer.isSqlSyntaxSupports() cho phép recognizer tự loại bỏ câu SQL không hỗ trợ; các bảng nằm trong govex.audit.ignore-tables cũng bị bỏ qua.
  • Danh sách method được phép trong mệnh đề WHERE có thể bổ sung qua SupportSqlWhereMethod (mặc định chỉ FIND_IN_SET).