Java의 준비된 상태는 어떻게 작동합니까?
-
03-07-2019 - |
문제
반복적으로 실행 된 명세서 개체를 대체 할 계획입니다. PreparedStatement
성능을 향상시키는 개체. MySQL 기능과 같은 인수를 사용하고 있습니다 now()
, 및 문자열 변수.
대부분의 PreparedStatement
내가 본 쿼리는 상수 값을 포함했습니다 (예 : 10
, 그리고 문자열 같은 "New York"
) ?
쿼리에서. 같은 기능을 사용하는 방법은 어떻게해야합니까? now()
, 및 인수로 변수? 사용해야합니다 ?
실제 값 대신 쿼리에 있습니까? 나는 꽤 혼란 스럽다.
해결책
변수가있는 경우 '?'
int temp = 75;
PreparedStatement pstmt = con.prepareStatement(
"UPDATE test SET num = ?, due = now() ");
pstmt.setInt(1, temp);
pstmt.executeUpdate():
다음과 같은 SQL 문을 생성합니다.
UPDATE test SET num = 75, due = now();
다른 팁
사용자 입력에서 나오는 변수가있는 경우 사용하는 것이 필수적입니까? 줄을 연결하는 대신. 사용자는 문자열을 악의적으로 입력 할 수 있으며 문자열을 SQL로 바로 삭제하면 의도하지 않은 명령을 실행할 수 있습니다.
나는 이것이 과도하게 사용된다는 것을 알고 있지만 완벽하게 말한다.
준비된 상태에서 자리 표시자를 사용할 필요가 없습니다. 같은 것 :
PreparedStatement stmt = con.prepareStatement("select sysdate from dual");
잘 작동합니다. 그러나 자리 표시자를 사용한 다음 기능 호출을 바인딩 할 수 없습니다. 이와 같은 것은 sysdate 함수를 호출하는 데 사용할 수 없습니다.
PreparedStatement stmt = con.prepareStatement("select ? from dual");
stmt.setSomethingOrOther(1, "sysdate");
SQL Server의 내장 기능을 호출하는 경우 사용하십시오. 준비된 상태.
SQL Server에로드 된 저장 프로 시저를 호출하는 경우 사용하십시오. CallableStatement.
통과하는 기능/절차 매개 변수 및 수신중인 기능/프로 시저 매개 변수의 자리 표시 자로 물음표를 사용하십시오.
SQL 쿼리에서 명명 된 매개 변수를 사용할 수있는 함수를 개발했습니다.
private PreparedStatement generatePreparedStatement(String query, Map<String, Object> parameters) throws DatabaseException
{
String paramKey = "";
Object paramValue = null;
PreparedStatement statement = null;
Pattern paramRegex = null;
Matcher paramMatcher = null;
int paramIndex = 1;
try
{
//Create the condition
paramRegex = Pattern.compile("(:[\\d\\w_-]+)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);
paramMatcher = paramRegex.matcher(query);
statement = this.m_Connection.prepareStatement(paramMatcher.replaceAll("?"),
ResultSet.TYPE_FORWARD_ONLY,
ResultSet.CONCUR_READ_ONLY,
ResultSet.HOLD_CURSORS_OVER_COMMIT);
//Check if there are parameters
paramMatcher = paramRegex.matcher(query);
while (paramMatcher.find())
{
paramKey = paramMatcher.group().substring(1);
if(parameters != null && parameters.containsKey(paramKey))
{
//Add the parameter
paramValue = parameters.get(paramKey);
if (paramValue instanceof Date)
{
statement.setDate(paramIndex, (java.sql.Date)paramValue);
}
else if (paramValue instanceof Double)
{
statement.setDouble(paramIndex, (Double)paramValue);
}
else if (paramValue instanceof Long)
{
statement.setLong(paramIndex, (Long)paramValue);
}
else if (paramValue instanceof Integer)
{
statement.setInt(paramIndex, (Integer)paramValue);
}
else if (paramValue instanceof Boolean)
{
statement.setBoolean(paramIndex, (Boolean)paramValue);
}
else
{
statement.setString(paramIndex, paramValue.toString());
}
}
else
{
throw new DatabaseException("The parameter '" + paramKey + "' doesn't exists in the filter '" + query + "'");
}
paramIndex++;
}
}
catch (SQLException l_ex)
{
throw new DatabaseException(tag.lib.common.ExceptionUtils.getFullMessage(l_ex));
}
return statement;
}
이 방법으로 사용할 수 있습니다.
Map<String, Object> pars = new HashMap<>();
pars.put("name", "O'Really");
String sql = "SELECT * FROM TABLE WHERE NAME = :name";