A high-performance JDBC connection pool and database monitoring library with SQL parsing and security features
—
Comprehensive SQL parsing, formatting, and manipulation capabilities supporting 50+ database dialects with full AST (Abstract Syntax Tree) manipulation and transformation features.
// Statement parsing
static List<SQLStatement> parseStatements(String sql, String dbType, SQLParserFeature... features);
static List<SQLStatement> parseStatements(String sql, DbType dbType, SQLParserFeature... features);
static List<SQLStatement> parseStatements(String sql, DbType dbType, boolean keepComments);
static List<SQLStatement> parseStatements(String sql, String dbType);
static List<SQLStatement> parseStatements(String sql, DbType dbType);
static SQLStatement parseSingleStatement(String sql, DbType dbType, boolean keepComments);
static SQLStatement parseSingleStatement(String sql, String dbType, SQLParserFeature... features);
static SQLStatement parseSingleStatement(String sql, DbType dbType, SQLParserFeature... features);
static SQLStatement parseSingleMysqlStatement(String sql);
// Expression and component parsing
static SQLExpr toSQLExpr(String sql, DbType dbType);
static SQLExpr toSQLExpr(String sql, DbType dbType, SQLParserFeature... features);
static SQLExpr toSQLExpr(String sql);
static SQLExpr toMySqlExpr(String sql);
static SQLSelectOrderByItem toOrderByItem(String sql, DbType dbType);
static SQLUpdateSetItem toUpdateSetItem(String sql, DbType dbType);
static SQLSelectItem toSelectItem(String sql, DbType dbType);
static List<SQLStatement> toStatementList(String sql, DbType dbType);// Generic SQL string conversion
static String toSQLString(SQLObject sqlObject, String dbType);
static String toSQLString(SQLObject sqlObject, DbType dbType);
static String toSQLString(SQLObject sqlObject, DbType dbType, FormatOption option);
static String toSQLString(SQLObject sqlObject, DbType dbType, FormatOption option, VisitorFeature... features);
static String toSQLString(SQLObject obj);
static String toSQLString(List<SQLStatement> statementList, DbType dbType);
static String toSQLString(List<SQLStatement> statementList, DbType dbType, FormatOption option);
static String toSQLString(List<SQLStatement> statementList, DbType dbType, List<Object> parameters);
static String toSQLString(List<SQLStatement> statementList, DbType dbType, List<Object> parameters, FormatOption option);
static String toSQLString(List<SQLStatement> statementList, DbType dbType, SQLASTOutputVisitor visitor);
// Database-specific string conversion
static String toOdpsString(SQLObject sqlObject);
static String toOdpsString(SQLObject sqlObject, FormatOption option);
static String toHiveString(SQLObject sqlObject);
static String toAntsparkString(SQLObject sqlObject);
static String toAntsparkString(SQLObject sqlObject, FormatOption option);
static String toMySqlString(SQLObject sqlObject);
static String toMySqlString(SQLObject sqlObject, VisitorFeature... features);
static String toMySqlString(SQLObject sqlObject, FormatOption option);
static String toMySqlStringIfNotNull(SQLObject sqlObject, String defaultStr);
static String toNormalizeMysqlString(SQLObject sqlObject);
static String toOracleString(SQLObject sqlObject);
static String toOracleString(SQLObject sqlObject, FormatOption option);
static String toPGString(SQLObject sqlObject);
static String toPGString(SQLObject sqlObject, FormatOption option);
static String toDB2String(SQLObject sqlObject);
static String toDB2String(SQLObject sqlObject, FormatOption option);
static String toSQLServerString(SQLObject sqlObject);
static String toSQLServerString(SQLObject sqlObject, FormatOption option);// Generic formatting
static String format(String sql, String dbType);
static String format(String sql, DbType dbType);
static String format(String sql, DbType dbType, FormatOption option);
static String format(String sql, DbType dbType, List<Object> parameters);
static String format(String sql, DbType dbType, List<Object> parameters, FormatOption option);
static String format(String sql, DbType dbType, List<Object> parameters, FormatOption option, SQLParserFeature[] features);
// Database-specific formatting
static String formatMySql(String sql);
static String formatMySql(String sql, FormatOption option);
static String formatOracle(String sql);
static String formatOracle(String sql, FormatOption option);
static String formatOdps(String sql);
static String formatOdps(String sql, FormatOption option);
static String formatPresto(String sql);
static String formatPresto(String sql, FormatOption option);
static String formatHive(String sql);
static String formatHive(String sql, FormatOption option);
static String formatSQLServer(String sql);
static String formatPGSql(String sql, FormatOption option);// Condition manipulation
static String addCondition(String sql, String condition, DbType dbType);
static String addCondition(String sql, String condition, SQLBinaryOperator op, boolean left, DbType dbType);
static void addCondition(SQLStatement stmt, SQLBinaryOperator op, SQLExpr condition, boolean left);
static SQLExpr buildCondition(SQLBinaryOperator op, SQLExpr condition, boolean left, SQLExpr where);
// Select item manipulation
static String addSelectItem(String selectSql, String expr, String alias, DbType dbType);
static String addSelectItem(String selectSql, String expr, String alias, boolean first, DbType dbType);
static void addSelectItem(SQLStatement stmt, SQLExpr expr, String alias, boolean first);
static void addSelectItem(SQLSelectQueryBlock queryBlock, SQLExpr expr, String alias, boolean first);
// SQL transformation
static String translateOracleToMySql(String sql);
static String refactor(String sql, DbType dbType, Map<String, String> tableMapping);
static String sort(String sql, DbType dbType);
static Object[] clearLimit(String query, DbType dbType);
static SQLLimit getLimit(SQLStatement statement, DbType dbType);
static SQLLimit getLimit(String query, DbType dbType);
static List<SQLInsertStatement> splitInsertValues(DbType dbType, String insertSql, int size);// SQL analysis
static long hash(String sql, DbType dbType);
static List<SQLExpr> split(SQLBinaryOpExpr x);
static SQLExpr not(SQLExpr expr);
// Name and value utilities
static String normalize(String name);
static String normalize(String name, boolean isTrimmed);
static String normalize(String name, DbType dbType);
static String forcedNormalize(String name, DbType dbType);
static boolean nameEquals(SQLName a, SQLName b);
static boolean nameEquals(String a, String b);
static boolean isValue(SQLExpr expr);
static boolean isQuoteChar(char c);
static String removeQuote(String str);
// Security utilities
static String desensitizeTable(String tableName);
// Date/Time handling
static String buildToDate(String columnName, String tableAlias, String pattern, DbType dbType);
static String convertTimeZone(String sql, TimeZone from, TimeZone to);
static SQLStatement convertTimeZone(SQLStatement stmt, TimeZone from, TimeZone to);// AST node replacement
static boolean replaceInParent(SQLDataType expr, SQLDataType target);
static boolean replaceInParent(SQLExpr expr, SQLExpr target);
static boolean replaceInParent(SQLSelect cmp, SQLSelect dest);
static boolean replaceInParent(SQLTableSource cmp, SQLTableSource dest);
static boolean replaceInParent(SQLSelectQuery cmp, SQLSelectQuery dest);
static boolean replaceInParent(SQLStatement cmp, SQLStatement dest);// Visitor pattern support
static SQLASTOutputVisitor createOutputVisitor(StringBuilder out, DbType dbType);
static SQLASTOutputVisitor createFormatOutputVisitor(StringBuilder out, List<SQLStatement> statementList, DbType dbType);
static SchemaStatVisitor createSchemaStatVisitor(DbType dbType);
static SchemaStatVisitor createSchemaStatVisitor(List<SQLStatement> statementList, DbType dbType); // @Deprecated
static SchemaStatVisitor createSchemaStatVisitor(SchemaRepository repository);
static SchemaStatVisitor createSchemaStatVisitor(SchemaRepository repository, DbType dbType);// SQL component analysis with visitor pattern
static void acceptBooleanOr(String sql, DbType dbType, Consumer<SQLBinaryOpExprGroup> consumer);
static void acceptBinaryOpExprGroup(String sql, DbType dbType, Consumer<SQLBinaryOpExprGroup> consumer, Predicate<SQLBinaryOpExprGroup> filter);
static void acceptBinaryOpExpr(String sql, DbType dbType, Consumer<SQLBinaryOpExpr> consumer, Predicate<SQLBinaryOpExpr> filter);
static void acceptTableSource(String sql, DbType dbType, Consumer<SQLTableSource> consumer, Predicate<SQLTableSource> filter);
static void acceptSelectQueryBlock(String sql, DbType dbType, Consumer<SQLSelectQueryBlock> consumer, Predicate<SQLSelectQueryBlock> filter);
static void acceptAggregateFunction(String sql, DbType dbType, Consumer<SQLAggregateExpr> consumer, Predicate<SQLAggregateExpr> filter);
static void acceptFunction(String sql, DbType dbType, Consumer<SQLMethodInvokeExpr> consumer, Predicate<SQLMethodInvokeExpr> filter);
static void acceptInsertInto(String sql, DbType dbType, Consumer<SQLInsertInto> consumer, Predicate<SQLInsertInto> filter);// Database type enumeration supporting 50+ databases
enum DbType {
// Major relational databases
mysql, mariadb, tidb, polardbx, goldendb,
oracle, oceanbase_oracle, ali_oracle,
postgresql, greenplum, edb, gaussdb, hologres, redshift,
sqlserver, jtds,
// Cloud and big data platforms
odps, // MaxCompute
hive, spark, databricks,
clickhouse, presto, trino,
snowflake, bigquery,
// Other databases
db2, h2, sqlite, derby, hsqldb,
informix, teradata, sybase,
starrocks, doris, dm, kingbase,
// And 20+ more specialized databases
}import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.DbType;
// Parse single SQL statement
String sql = "SELECT id, name FROM users WHERE age > 18";
SQLStatement statement = SQLUtils.parseSingleStatement(sql, DbType.mysql);
// Parse multiple statements
String multipleSql = "INSERT INTO users (name) VALUES ('John'); SELECT * FROM users;";
List<SQLStatement> statements = SQLUtils.parseStatements(multipleSql, DbType.mysql);
// Parse with features
SQLStatement stmt = SQLUtils.parseSingleStatement(sql, DbType.mysql,
SQLParserFeature.KeepComments,
SQLParserFeature.KeepNameQuotes);// Parse expressions
SQLExpr expr = SQLUtils.toSQLExpr("age > 18 AND status = 'active'", DbType.mysql);
SQLSelectItem selectItem = SQLUtils.toSelectItem("COUNT(*) as total", DbType.mysql);
SQLOrderByItem orderBy = SQLUtils.toOrderByItem("name DESC", DbType.mysql);// Format option configuration class within SQLUtils
static class FormatOption {
// Constructors
public FormatOption();
public FormatOption(VisitorFeature... features);
public FormatOption(boolean ucase);
public FormatOption(boolean ucase, boolean prettyFormat);
public FormatOption(boolean ucase, boolean prettyFormat, boolean parameterized);
// Configuration methods
public boolean isUppCase();
public void setUppCase(boolean uppCase);
public boolean isPrettyFormat();
public void setPrettyFormat(boolean prettyFormat);
public boolean isParameterized();
public void setParameterized(boolean parameterized);
public boolean isDesensitize();
public void setDesensitize(boolean desensitize);
// Feature configuration
public void config(VisitorFeature feature, boolean state);
public void configTo(SQLASTOutputVisitor visitor);
public boolean isEnabled(VisitorFeature feature);
}
// Constants for default format options
static final FormatOption DEFAULT_FORMAT_OPTION = new FormatOption(true, true);
static final FormatOption DEFAULT_LCASE_FORMAT_OPTION = new FormatOption(false, true);import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.SQLUtils.FormatOption;
String sql = "select*from users where id=1";
// Basic formatting
String formatted = SQLUtils.format(sql, DbType.mysql);
// Result: SELECT *\nFROM users\nWHERE id = 1
// Pretty formatting with options
FormatOption option = new FormatOption(true, true); // uppercase, pretty
String prettyFormatted = SQLUtils.format(sql, DbType.mysql, option);
// Database-specific formatting
String mysqlFormatted = SQLUtils.formatMySql(sql, option);
String oracleFormatted = SQLUtils.formatOracle(sql, option);
String pgFormatted = SQLUtils.formatPostgreSQL(sql, option);// SQL manipulation methods
static String addCondition(String sql, String condition, SQLBinaryOperator op, boolean left, DbType dbType);
static String addSelectItem(String sql, String expr, String alias, boolean first, DbType dbType);
static String refactor(String sql, DbType dbType, Map<String, String> tableMapping);
static String normalize(String name, DbType dbType);
static List<SQLBinaryOpExpr> split(SQLBinaryOpExpr x);// Add WHERE condition
String originalSql = "SELECT * FROM users";
String withCondition = SQLUtils.addCondition(originalSql, "age > 18",
SQLBinaryOperator.BooleanAnd, false, DbType.mysql);
// Result: SELECT * FROM users WHERE age > 18
// Add SELECT item
String withColumn = SQLUtils.addSelectItem(originalSql, "created_date", "creation",
false, DbType.mysql);
// Result: SELECT *, created_date AS creation FROM users
// Refactor table names
Map<String, String> tableMapping = new HashMap<>();
tableMapping.put("users", "customers");
String refactored = SQLUtils.refactor("SELECT * FROM users", DbType.mysql, tableMapping);
// Result: SELECT * FROM customers// Parser creation
static SQLStatementParser createSQLStatementParser(String sql, DbType dbType, SQLParserFeature... features);
static SQLExprParser createExprParser(String sql, DbType dbType, SQLParserFeature... features);
static Lexer createLexer(String sql, DbType dbType, SQLParserFeature... features);
// SQL analysis
static SQLType getSQLType(String sql, DbType dbType);
static boolean containsAny(String sql, DbType dbType, Token... tokens);
static Object getSimpleSelectValue(String sql, DbType dbType);
static List<String> split(String sql, DbType dbType);
static String removeComment(String sql, DbType dbType);
static Collection<String> getTables(String sql, DbType dbType);import com.alibaba.druid.sql.parser.SQLParserUtils;
import com.alibaba.druid.sql.parser.Token;
// Determine SQL statement type
SQLType type = SQLParserUtils.getSQLType("SELECT * FROM users", DbType.mysql);
// Returns: SQLType.SELECT
// Extract table names
Collection<String> tables = SQLParserUtils.getTables(
"SELECT u.id, p.name FROM users u JOIN profiles p ON u.id = p.user_id",
DbType.mysql);
// Returns: ["users", "profiles"]
// Remove comments
String cleaned = SQLParserUtils.removeComment(
"SELECT * FROM users -- get all users", DbType.mysql);
// Returns: "SELECT * FROM users"
// Split multi-statement SQL
List<String> statements = SQLParserUtils.split(
"INSERT INTO users (name) VALUES ('John'); SELECT * FROM users;",
DbType.mysql);// Pagination methods
class PagerUtils {
static String limit(String sql, DbType dbType, int offset, int count, boolean check);
static String count(String sql, DbType dbType);
static PagerUtils.Limit getLimit(String sql, DbType dbType);
static boolean hasUnorderedLimit(String sql, DbType dbType);
}import com.alibaba.druid.sql.PagerUtils;
String sql = "SELECT * FROM users ORDER BY name";
// Add pagination
String pagedSql = PagerUtils.limit(sql, DbType.mysql, 20, 10, true);
// Result: SELECT * FROM users ORDER BY name LIMIT 20, 10
// Convert to count query
String countSql = PagerUtils.count(sql, DbType.mysql);
// Result: SELECT COUNT(*) FROM users
// Extract existing limit
PagerUtils.Limit limit = PagerUtils.getLimit(
"SELECT * FROM users LIMIT 10, 20", DbType.mysql);
// Returns limit object with offset=10, rowCount=20// Base AST interfaces
interface SQLObject {
void accept(SQLASTVisitor visitor);
SQLObject clone();
String toString();
}
interface SQLStatement extends SQLObject {
DbType getDbType();
void setDbType(DbType dbType);
List<SQLCommentHint> getHeadHintsDirect();
}
interface SQLExpr extends SQLObject {
SQLExpr clone();
boolean equals(Object o);
int hashCode();
}// Statement implementations
class SQLSelectStatement implements SQLStatement {
public SQLSelectQuery getSelect();
public void setSelect(SQLSelectQuery select);
}
class SQLInsertStatement implements SQLStatement {
public SQLExprTableSource getTableSource();
public List<SQLExpr> getColumns();
public SQLInsertStatement.ValuesClause getValues();
}
class SQLUpdateStatement implements SQLStatement {
public SQLTableSource getTableSource();
public List<SQLUpdateSetItem> getItems();
public SQLExpr getWhere();
}// Main visitor interface
interface SQLASTVisitor {
// Visit methods for all AST node types
boolean visit(SQLSelectStatement x);
void endVisit(SQLSelectStatement x);
boolean visit(SQLInsertStatement x);
void endVisit(SQLInsertStatement x);
// ... hundreds more visit methods
}
// Output visitor for generating SQL
class SQLASTOutputVisitor implements SQLASTVisitor {
public SQLASTOutputVisitor(StringBuilder out);
public SQLASTOutputVisitor(StringBuilder out, DbType dbType);
public String getSql();
}import com.alibaba.druid.sql.visitor.SQLASTOutputVisitor;
import com.alibaba.druid.sql.visitor.SchemaStatVisitor;
// Generate SQL from AST
StringBuilder out = new StringBuilder();
SQLASTOutputVisitor visitor = new SQLASTOutputVisitor(out, DbType.mysql);
statement.accept(visitor);
String sql = visitor.getSql();
// Analyze schema information
SchemaStatVisitor schemaVisitor = new SchemaStatVisitor(DbType.mysql);
statement.accept(schemaVisitor);
Set<TableStat.Name> tables = schemaVisitor.getTables().keySet();
Set<TableStat.Column> columns = schemaVisitor.getColumns();// Parser feature flags
enum SQLParserFeature {
KeepComments, // Preserve SQL comments
KeepNameQuotes, // Preserve identifier quotes
EnableSQLBinaryOpExprGroup, // Group binary operations
OptimizedForParameterized, // Optimize for parameterized queries
StrictForWall, // Enable security wall features
IgnoreNameQuotes, // Ignore identifier quotes
InsertReader, // Optimized INSERT parsing
// ... more features
}// Exception classes
class ParserException extends RuntimeException {
public ParserException(String message);
public ParserException(String message, Throwable cause);
public int getLine();
public int getColumn();
}
class SQLParseException extends ParserException {
public SQLParseException(String message);
public SQLParseException(String message, Throwable cause);
}
class FastsqlException extends RuntimeException {
public FastsqlException(String message);
public FastsqlException(String message, Throwable cause);
}import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.sql.ast.statement.SQLSelectStatement;
import com.alibaba.druid.sql.ast.statement.SQLSelectQuery;
import com.alibaba.druid.sql.visitor.SQLASTOutputVisitor;
// Parse complex query
String complexSql = """
SELECT u.id, u.name, p.title, COUNT(o.id) as order_count
FROM users u
LEFT JOIN profiles p ON u.id = p.user_id
LEFT JOIN orders o ON u.id = o.user_id
WHERE u.active = 1
GROUP BY u.id, u.name, p.title
HAVING COUNT(o.id) > 5
ORDER BY order_count DESC
LIMIT 100
""";
SQLStatement stmt = SQLUtils.parseSingleStatement(complexSql, DbType.mysql);
// Transform and regenerate
StringBuilder output = new StringBuilder();
SQLASTOutputVisitor visitor = new SQLASTOutputVisitor(output, DbType.postgresql);
stmt.accept(visitor);
String postgresqlSql = visitor.getSql();// Oracle to MySQL translation
String oracleSql = "SELECT * FROM users WHERE ROWNUM <= 10";
String mysqlSql = SQLUtils.translateOracleToMySql(oracleSql);
// Result: SELECT * FROM users LIMIT 10
// Format for different databases
String baseSql = "select id,name from users where active=1";
String mysqlFormatted = SQLUtils.formatMySql(baseSql, new FormatOption(true, true));
String oracleFormatted = SQLUtils.formatOracle(baseSql, new FormatOption(true, true));
String pgFormatted = SQLUtils.formatPostgreSQL(baseSql, new FormatOption(true, true));This comprehensive SQL processing framework provides enterprise-grade capabilities for parsing, analyzing, transforming, and generating SQL across multiple database platforms with full programmatic control over SQL structure and formatting.
Install with Tessl CLI
npx tessl i tessl/maven-com-alibaba--druid