Я разрабатывал некоторый исходный код, потому что в нашем проекте много кода повторялось при выполнении SQL-запросов.Java - Как сделать переопределение метода обязательным в дочерних анонимных классах?
Итак, я сделал этот код ниже, который, кажется, отлично работает, используя что-то похожее на шаблон команды. Он получает только SQL-запрос в String и некоторые параметры (если необходимо) для установки в инструкции. Таким образом, вы можете использовать этот код как анонимный класс, чтобы выполнить запрос, определяя, что делать с выходом запроса.
Моя проблема заключается в том, что я хотел создать это, чтобы сделать обязательным определение и запись метода getResult в анонимном дочернем классе, но я не могу думать об этом, не делая абстрактного метода и класса.
Если QueryCommand становится абстрактным, я должен сделать еще один класс, чтобы иметь возможность создавать экземпляр, что также не может быть абстрактным. Есть ли другой способ сделать обязательным переопределение в классе детей? Я ищу самый умный простейший способ добиться этого.
Не знал, как искать подобный шаблон или решение.
Заранее спасибо.
код Источник:
import java.sql.Connection;
import java.sql.SQLException;
public interface IQueryCommand<T> {
T executeQuery(Connection conn, String query, Object... args) throws SQLException;
}
import java.math.BigDecimal;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.MessageFormat;
import org.apache.log4j.Logger;
public class QueryCommand<T> implements IQueryCommand<T> {
private Logger LOGGER = Logger.getLogger(this.getClass());
/** The constant ERROR_CLOSING_RESULT_SET */
protected static final String ERROR_CLOSING_RESULT_SET = "Error when closing ResultSet";
/** The Constant ERROR_CLOSING_PREPARED_STATEMENT. */
protected static final String ERROR_CLOSING_PREPARED_STATEMENT = "Error when closing PreparedStatement";
// FIXME: I want this method to be mandatory to be defined in the anonymous child class
protected T getResult(ResultSet rs) throws SQLException {
return null;
};
public T executeQuery(Connection conn, String sqlQuery, Object... args) throws SQLException {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug(sqlQuery);
}
PreparedStatement ps = null;
ps = conn.prepareStatement(sqlQuery);
return executeQuery(conn, ps, args);
}
public T executeQuery(Connection conn, PreparedStatement ps, Object... args) throws SQLException {
ResultSet rs = null;
try {
if(args != null && args.length > 0) {
for(int i=0; i< args.length; i++) {
setArg(ps, i+1, args[i]);
}
}
rs = ps.executeQuery();
T result = getResult(rs); // Method defined in child class
return result;
} catch (SQLException e) {
throw e;
} finally {
if(rs != null) {
try {
rs.close();
} catch (final SQLException e) {
LOGGER.error(ERROR_CLOSING_RESULT_SET, e);
}
}
if (ps != null) {
try {
ps.close();
} catch (final Exception e) {
if(ps instanceof CallableStatement) {
LOGGER.error("Error when closing CallableStatement", e);
} else if(ps instanceof PreparedStatement) {
LOGGER.error(ERROR_CLOSING_PREPARED_STATEMENT, e);
}
}
}
}
}
/**
* Sets a value on the PreparedStatemente with a method dependending on dataType
*
* @param ps the preparedStatement
* @param idx the index on which the value is set
* @param value the value to set
* @throws SQLException if an error is detected
*/
private void setArg(PreparedStatement ps, int idx, Object value) throws SQLException {
// Implementation not relevant...
}
}
Пример того, как использовать этот:
sqlQuery = " SELECT X FROM Y WHERE countryId = ? and languageId = ?";
return new QueryCommand<String>() {
// This method should be REQUIRED when compiling
@Override
protected String getResult(ResultSet rs) throws SQLException {
String result = "";
while (rs.next()) {
result = rs.getString("DESCRIPTION");
}
return result;
};
}.executeQuery(getDB2Connection(), sqlQuery.toString(), new Object[] { countryIdParameter, languageIdParameter});
Вы, кажется, знаете что делать: сделайте аннотация «QueryCommand». Что за вопрос? –
Отличный вопрос! : P –