没有办法忽略该Connection
对象,连接也不是真正可重用的,除非你有一个连接池,但它们仍然需要关闭才能让池知道它们可以再次使用。但是,如果你想封装sql
,你可以尝试这样的事情:
enum CallableEnum {
CALLABLE_ONE("insert_new_cat", 3),
CALLABLE_TWO("update_cat", 2),
;
private String sql;
private int parameterCount;
private CallableEnum(String sql, int params) {
this.sql = sql;
this.parameterCount = params;
}
public CallableStatement prepare(Connection connection) throws SQLException {
final StringBuilder builder = new StringBuilder("{CALL ");
builder.append(this.sql);
builder.append("(");
int count = this.parameterCount;
for (int i = 0; i < count; i++) {
builder.append("?");
if (i != count - 1) {
builder.append(", ");
}
}
return connection.prepareCall(builder.append(")}").toString());
}
}
然后像这样使用它:
Connection conn = DriverManager.getConnection("foo");
CallableStatement statement = CallableEnum.CALLABLE_ONE.prepare(conn);
for (Cat currentCat : catList) {
generateCatId(currentCat.name(), currentCat.age(), statement);
}
conn.commit();
conn.close();
显然你可以修改它以满足你的需要,这是我能从你的问题中得到的唯一想法:)
更新
好的,这看起来很疯狂,我还没有测试过,但我修改了它以封装所有内容:
enum CallableEnum {
CALLABLE_ONE("insert_new_cat", 3, new Executable<Long>() {
@Override
public Long apply(CallableStatement statement, Object... arguments) throws SQLException {
statement.setString(1, String.valueOf(arguments[0]));
statement.setInt(2, Integer.parseInt(String.valueOf(arguments[1])));
statement.registerOutParameter(3, Types.NUMERIC);
statement.execute();
return statement.getLong(3);
}
}),
;
private String sql;
private Executable<?> executable;
private int parameterCount;
private CallableEnum(String sql, int params, Executable<?> todo) {
this.sql = sql;
this.parameterCount = params;
this.executable = todo;
}
public CallableStatement prepare(Connection connection) throws SQLException {
final StringBuilder builder = new StringBuilder("{CALL ");
builder.append(this.sql);
builder.append("(");
int count = this.parameterCount;
for (int i = 0; i < count; i++) {
builder.append("?");
if (i != count - 1) {
builder.append(", ");
}
}
return connection.prepareCall(builder.append(")}").toString());
}
public <T> T execute(Connection conn, Object... arguments) throws SQLException {
CallableStatement st = this.prepare(conn);
return (T) this.executable.apply(st, arguments);
}
private interface Executable<T> {
T apply(CallableStatement st, Object... arguments) throws SQLException;
}
}
现在可以像这样使用它:
Connection conn = DriverManager.getConnection("foo");
for (Cat currentCat : catList) {
CallableEnum.CALLABLE_ONE.execute(conn, currentCat.name(), currentCat.age());
}
conn.commit();
conn.close();
我不知道这是否是您想要的,或者即使它会起作用,但我会留给您的 :)