日期:2014-05-16  浏览次数:20334 次

针对MySQL数据库过滤SQL查询参数(JAVA实现)

/**
* 过滤SQL参数,防止特殊字符引发的异常和SQL注入
* 只适用于MySQL数据库
* @author sodarfish
* @since 2008.1.21
* @update 2008.1.24
*/
public class SQLFilter{
?? public static final int NUMBER_FOR_QUERY=0;
?? public static final int MYSQL_CHAR_FOR_UPDATE=1;
?? public static final int MYSQL_CHAR_FOR_NONLIKE_QUERY=2;
?? public static final int MYSQL_CHAR_FOR_LIKE_QUERY=3;
?? public static final int MYSQL_P_CHAR_FOR_LIKE_QUERY=4;
?? /**
?? * 针对MySQL使用Statement和PreparedStatement进行插入和查询时的参数
?? * 进行合法化。
?? * 由于MS SQLServer 默认没有用\做转义符,在处理普通操作时,只需要注意'转为''就可以了.
?? * 如果用PreparedStatement,那么这一步也可以免掉.
?? * 如果要查询%符号,那么在MSSQLSERVER中必须使用escape 进行转义,如果使用了escape '\'
?? * 可以使用该类的MYSQL_P_CHAR_FOR_LIKE_QUERY来指定过滤类型.
?? * @param sql
?? * @param paramType
?? * @return
?? */
?? public static String filtrateSQL(String sql,int paramType){
?? ??? if(sql==null){
?? ??? ??? //throw new IllegalArgumentException("参数为空!");
?? ??? ??? return null;
?? ??? }
?? ??? //识别参数是否是数字
?? ??? if(paramType==SQLFilter.NUMBER_FOR_QUERY){
?? ??? ??? Pattern pattern = Pattern.compile("(0|[1-9])[0-9]*(\\.[0-9]*)?");
?? ??? ??? if(pattern.matcher(sql).matches())
?? ??? ??? ??? return sql;
?? ??? ??? else
?? ??? ??? ??? //throw new IllegalArgumentException("非法参数!");
?? ??? ??? ??? return null;
?? ??? }
?? ??? //MySQL处理插入操作.将特殊字符加上转义
?? ??? if(paramType==SQLFilter.MYSQL_CHAR_FOR_UPDATE){
?? ??? ??? String newKey=sql.replaceAll("\\\\","\\\\\\\\");//处理\插入
?? ??? ??? newKey=newKey.replaceAll("'","\\\\'");?? //处理'插入防止SQL注入
?? ??? ??? newKey=newKey.replaceAll("\"","\\\\\"");
?? ??? ??? return newKey;
?? ??? }
?? ???
?? ??? //MySQL处理非LIKE匹配查询操作.将特殊字符加上转义
?? ??? if(paramType==SQLFilter.MYSQL_CHAR_FOR_NONLIKE_QUERY){
?? ??? ??? String newKey=sql.replaceAll("\\\\","\\\\\\\\");//处理\插入
?? ??? ??? newKey=newKey.replaceAll("'","\\\\'");?? //处理'插入防止SQL注入
?? ??? ??? newKey=newKey.replaceAll("\"","\\\\\"");
?? ??? ??? return newKey;
?? ??? }
?? ??? /**
?? ??? * 对于MySQL 使用Statement对象进行LIKE模糊匹配的特殊处理.
?? ??? *
?? ??? */
?? ??? if(paramType==SQLFilter.MYSQL_CHAR_FOR_LIKE_QUERY){
?? ??? ??? //处理查询特殊字符首先处理\,因为它有转义作用,在MySQL LIKE匹配中,
?? ??? ??? //会出现两次转义,因此实际查询一个\符号,在SQL语句中的输入应当是\\\\,
?? ??? ??? //这里由于加上方法中对正则表达式的转义要求和JAVA本身的转义要求,输入16个\
?? ??? ??? //恰好表示SQL中4个\
?? ??? ??? //然后处理其他特殊字符,他们在SQL中表示为\% \'等.
?? ??? ??? String newKey=sql;
?? ??? ??? newKey=newKey.replaceAll("\\\\","\\\\\\\\\\\\\\\\");
?? ??? ??? newKey=newKey.replaceAll("'","\\\\'");
?? ??? ??? newKey=newKey.replaceAll("_","\\\\_");
?? ??? ??? newKey=newKey.replaceAll("%", "\\\\%");
?? ??? ??? newKey=newKey.replaceAll("\"","\\\\\"");
?? ??? ???
?? ??? ??? return newKey;
?? ??? }
?? ??? /**
?? ??? * 对于MySQL 使用PreparedStatement对象进行LIKE模糊匹配的特殊处理.
?? ??? * 对MySQL来说,使用PreparedStatement时,只需要特殊处理LIKE匹配问题.
?? ??? *
?? ??? * 此方法还适用于MSSQL Server2000中,Like 匹配使用了 escape '\'的语句.
?? ??? */
?? ??? if(paramType==SQLFilter.MYSQL_P_CHAR_FOR_LIKE_QUERY){
?? ??? ??? //由于MySQL中\为默认转义字符
?? ??? ??? //处理参数中的特殊字符,\用\\转义成普通的\字符.
?? ??? ???
?? ??? ??? String newKey=sql;
?? ??? ??? newKey=newKey.replaceAll("\\\\","\\\\\\\\");
?? ??? ??? newKey=newKey.replaceAll("'","\\\\'");
?? ??? ??? newKey=newKey.replaceAll("_","\\\\_");
?? ??? ??? newKey=newKey.replaceAll("%", "\\\\%");
?? ??? ??? newKey=newKey.replaceAll("\"","\\\\\"");
?? ??? ???
?? ??? ??? return newKey;
?? ??? }
?? ??? return null;
?? }