컨텐츠 바로가기

PreparedStatement 쿼리 문장의 ?를 파라미터 값으로 대치하기

http://kwon37xi.egloos.com/1897209

iBatis로 개발하면서 로그로 찍힌 쿼리를 SQL 실행기 등으로 테스트 하기 위해 만든 것이다.

JSP이므로 톰캣에 아무데나 넣어서 호출해보면 금방 알 수 있다.

* JoinQuery.jsp

<%@ page language="java" contentType="text/html; charset=euc-kr"%>
<%@ page import="java.util.*"%>
<%!
/** 파라미터 개수 */
public static final int NUMBER_OF_PARAMS = 20;

/** 쿼리와 파라미터 합치기 */
public static String joinQuery(String query, String [] params, String [] isString) {
    int currentIndex = query.indexOf('?');
    if (currentIndex < 0) {
        return query;
    }
    StringBuffer resultQuery = new StringBuffer(query.substring(0, currentIndex));

    int countOfQuestionMark = getCountOfQuestionMark(query);
    System.out.println("물음표 개수 : " + countOfQuestionMark);

    for (int i = 0; i < countOfQuestionMark; i++) {
        if (params[i] == null) {
            resultQuery.append("NULL");
        } else if (isChecked(isString, i)) {
            resultQuery.append(converToSqlString(params[i]));
        } else {
            resultQuery.append(params[i]);
        }

        if (i == countOfQuestionMark - 1) {
            resultQuery.append(query.substring(currentIndex + 1));
        } else {
            int nextIndex = query.indexOf('?', currentIndex + 1);
            resultQuery.append(query.substring(currentIndex + 1, nextIndex));
            currentIndex = nextIndex;
        }
    }

    return resultQuery.toString();
}

/** 문자열로 지정된 것인가? */
public static boolean isChecked(String [] isString, int value) {
    if (isString == null) {
        return false;
    }

    String valueStr = String.valueOf(value);
    for (int i=0; i < isString.length; i++) {
        if (valueStr.equals(isString[i])) {
            return true;
        }
    }
    return false;
}

/** 문자열에 들어 있는 ' 를 ''로 바꾼다. */
public static String converToSqlString(String str) {
    return "'" + str.replaceAll("'", "''") + "'";
}

/** 문자열에 포함된 ?의 개수 */
public static int getCountOfQuestionMark(String str) {
    int count = 0;
    int currentIndex = 0;
    String temp = str;
    while ((currentIndex = temp.indexOf("?", currentIndex)) > 0) {
        count++;
        currentIndex++;
    }

    return count;
}

/** HTML 특수문자 변환 */
public static String value(String str) {
    if (str == null) {
        return "";
    }

    String temp = str;
    temp = temp.replaceAll("&", "&amp;");
    temp = temp.replaceAll("<", "&lt;");
    temp = temp.replaceAll(">", "&gt;");
    temp = temp.replaceAll(""", "&quot;");
    return temp;
}

public static String value(String [] params, int index) {
    if (params == null) {
        return "";
    } else if (index >= params.length) {
        return "";
    }

    return value(params[index]);
}
%>

<%
request.setCharacterEncoding("euc-kr");

String query = request.getParameter("query");
String [] params = request.getParameterValues("params");
String [] isString = request.getParameterValues("isstring");
%>
<html>
    <head>
        <title>쿼리와 파라미터 합치기</title>
    </head>
    <body>
    <h1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;== 쿼리 합치기 ==</h1>

    <%if (query != null && query.trim().length() > 0) { %>
        <h2>쿼리 합친 결과</h2>
        <textarea rows="15" cols="120" style="font-size: 12px;"><%= joinQuery(query, params, isString) %></textarea>
    <hr />
    <%} %>
    <form action="JoinQuery.jsp" method="post">
        <div><b>아래에 PreparedStatement 쿼리 문장을 넣으세요</b></div>
        <textarea name="query" rows="6" cols="120" style="font-size: 12px;"><%=value(query)%></textarea><br />
        <div><b>아래에 파라미터 목록을 넣으세요</b></div>
        <%for (int i=0; i < NUMBER_OF_PARAMS; i++) { %>
            <input style="font-size: 12px;" name="isstring" type="checkbox" value="<%=i%>" <%=isChecked(isString, i) ? "checked" : "" %> /> 문자형?
            <input style="font-size: 12px;" name="params" type=text" width="120" size="120" value="<%=value(params, i)%>"/>
            <br />
        <%} %>
        <input type="submit" value="합치기" />
    </form>
    </body>
</html>


덧글|덧글 쓰기|신고