package jef.database.routing.sql; import java.sql.SQLException; import java.util.regex.Pattern; import jef.database.routing.jdbc.SqlType; import jef.tools.StringUtils; public class SqlTypeParser { /** * 用于判断是否是一个select ... for update的sql */ private static final Pattern SELECT_FOR_UPDATE_PATTERN = Pattern.compile("^select\\s+.*\\s+for\\s+update.*$", Pattern.CASE_INSENSITIVE); public static boolean isQuerySql(String sql) throws SQLException { SqlType sqlType = getSqlType(sql); if (sqlType == SqlType.SELECT || sqlType == SqlType.SELECT_FOR_UPDATE || sqlType == SqlType.SHOW || sqlType == SqlType.DUMP || sqlType == SqlType.DEBUG || sqlType == SqlType.EXPLAIN) { return true; } else if (sqlType == SqlType.INSERT || sqlType == SqlType.UPDATE || sqlType == SqlType.DELETE || sqlType == SqlType.REPLACE || sqlType == SqlType.TRUNCATE || sqlType == SqlType.CREATE || sqlType == SqlType.DROP || sqlType == SqlType.LOAD || sqlType == SqlType.MERGE || sqlType == SqlType.ALTER || sqlType == SqlType.RENAME) { return false; } else { return throwNotSupportSqlTypeException(); } } /** * 获得SQL语句种类 * * @param sql * SQL语句 * @throws SQLException * 当SQL语句不是SELECT、INSERT、UPDATE、DELETE语句时,抛出异常。 */ public static SqlType getSqlType(String sql) throws SQLException { SqlType sqlType = null; String noCommentsSql = sql; if (StringUtils.startsWithIgnoreCaseAndWs(noCommentsSql, "select")) { if (noCommentsSql.toLowerCase().contains(" for ") && SELECT_FOR_UPDATE_PATTERN.matcher(noCommentsSql).matches()) { sqlType = SqlType.SELECT_FOR_UPDATE; } else { sqlType = SqlType.SELECT; } } else if (StringUtils.startsWithIgnoreCaseAndWs(noCommentsSql, "insert")) { sqlType = SqlType.INSERT; } else if (StringUtils.startsWithIgnoreCaseAndWs(noCommentsSql, "update")) { sqlType = SqlType.UPDATE; } else if (StringUtils.startsWithIgnoreCaseAndWs(noCommentsSql, "delete")) { sqlType = SqlType.DELETE; } else if (StringUtils.startsWithIgnoreCaseAndWs(noCommentsSql, "show")) { sqlType = SqlType.SHOW; } else if (StringUtils.startsWithIgnoreCaseAndWs(noCommentsSql, "replace")) { sqlType = SqlType.REPLACE; } else if (StringUtils.startsWithIgnoreCaseAndWs(noCommentsSql, "truncate")) { sqlType = SqlType.TRUNCATE; } else if (StringUtils.startsWithIgnoreCaseAndWs(noCommentsSql, "create")) { sqlType = SqlType.CREATE; } else if (StringUtils.startsWithIgnoreCaseAndWs(noCommentsSql, "drop")) { sqlType = SqlType.DROP; } else if (StringUtils.startsWithIgnoreCaseAndWs(noCommentsSql, "load")) { sqlType = SqlType.LOAD; } else if (StringUtils.startsWithIgnoreCaseAndWs(noCommentsSql, "merge")) { sqlType = SqlType.MERGE; } else if (StringUtils.startsWithIgnoreCaseAndWs(noCommentsSql, "alter")) { sqlType = SqlType.ALTER; } else if (StringUtils.startsWithIgnoreCaseAndWs(noCommentsSql, "rename")) { sqlType = SqlType.RENAME; } else if (StringUtils.startsWithIgnoreCaseAndWs(noCommentsSql, "dump")) { sqlType = SqlType.DUMP; } else if (StringUtils.startsWithIgnoreCaseAndWs(noCommentsSql, "debug")) { sqlType = SqlType.DEBUG; } else if (StringUtils.startsWithIgnoreCaseAndWs(noCommentsSql, "explain")) { sqlType = SqlType.EXPLAIN; } else { throwNotSupportSqlTypeException(); } return sqlType; } public static boolean throwNotSupportSqlTypeException() throws SQLException { throw new SQLException("only select, insert, update, delete, replace, show, truncate, create, drop, load, merge, dump sql is supported"); } }