Я написал следующее, но не уверен, что это достаточно правильно и самый простой способ.< /p>
Я создаю строку SQL для вставки строки данных.
Из моего источника данных (пула хикари) я получаю соединение с базой данных. Затем я создаю подготовленный оператор, выполняю его и получаю обратно ResultSet.
Этот набор результатов я возвращаю вызывающей стороне.
Соединение и подготовленный оператор должны оставаться открытыми до тех пор, пока вызывающая сторона не будет готова с возвращенным набором результатов
Код: Выделить всё
public DbResult insert(int cache, String shema, String table, LinkedHashMap data, boolean returnAutoCreate) throws SQLException
{
//building sql-string or take it from my cache
//...
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
try
{
connection = ds.getConnection();
preparedStatement = connection.prepareStatement(sqlString);
int i = 0;
for (Object value : data.values())
{
preparedStatement.setObject(i++, value);
}
preparedStatement.executeUpdate();
resultSet = preparedStatement.getResultSet();
DbResult dbResult = new DbResult(connection, preparedStatement, resultSet);
return dbResult;
}
catch (Exception e)
{
try
{
if (resultSet != null) resultSet.close();
}
catch (Exception e2)
{
e.addSuppressed(e2);
}
try
{
if (preparedStatement != null) preparedStatement.close();
}
catch (Exception e2)
{
e.addSuppressed(e2);
}
try
{
if (connection != null) connection.close();
}
catch (Exception e2)
{
e.addSuppressed(e2);
}
throw e;
}
}
Код: Выделить всё
class DbResult implements AutoCloseable
{
private final ResultSet rs;
private final PreparedStatement ps;
private final Connection conn;
public DbResult(Connection conn, PreparedStatement ps, ResultSet rs)
{
this.conn = conn;
this.ps = ps;
this.rs = rs;
}
@Override
public void close() throws SQLException
{
try (conn; ps; rs;){}
}
public ResultSet getResultSet()
{
return rs;
}
}
Код: Выделить всё
DatabaseHelper databaseHelper = new DatabaseHelper(ds, defaultShema);
try(DbResult result = databaseHelper.insert(1001, defaultShema, "test", new LinkedHashMap(), true);)
{
//do sth with result
}
Если проблем нет, Я добавляю ресурсы в свой объект DbResult и закрываю их с помощью метода close(). При этом я использую попытку, потому что, если в этой цепочке одно закрытие завершается неудачно, остальные все равно закрываются, и исключение пересылается правильно.
В вызывающем объекте я использую также попытка, которая вызывает метод close() в DbResult после того, как я закончил обработку результата.
Но это много кода, особенно попытка -catch в моем методе вставки.
Я не уверен, есть ли более простой или лучший способ сделать это.
У меня есть еще один вопрос:
Я мог бы кэшировать результат, чтобы мне не приходилось заботиться о закрытии этого ресурса за пределами моего класса DatabaseHelper.
Существует CachedRowSet. Но я не уверен, насколько это дорого. Копирует ли это также метаинформацию?
Я думаю, обычный ResultSet сначала извлекает данные, если я обращаюсь к ним:
метаданные, данные строк: построчно?
Хороша ли идея кэшировать данные в ArrayList хэш-карт?
Код: Выделить всё
Arraylist -> Rows
HashMap -> columns by name -> value
Мне не нужно беспокоиться об этом закрытии за пределами моего класса базы данных, пул быстрее восстанавливает соединение.
Однако, возможно, я получаю данные, которые мне не нужны (например, метаданные).
Кроме того, создание копии моих данных в конструкции ArrayList->Hashmap обходится дорого.
Итак, какие у вас идеи по этому поводу? какова наилучшая практика?
Подробнее здесь: https://stackoverflow.com/questions/580 ... mplex-apis
Мобильная версия