Java попробуй на сложном apis - PullRequest
0 голосов
/ 23 сентября 2019

Я хочу обернуть некоторый код JDBC в свои и разные классы.Таким образом, ресурс создается в этих классах, набор результатов возвращается.Если клиент готов, все открытые ресурсы в этой цепочке должны быть закрыты.

Я написал следующее, но я не уверен, что это достаточно правильно и проще всего.

Я строю строку SQL для вставки строки данных.

Из моего источника данных (пул хикари) я получаю соединение с базой данных.Затем я создаю подготовленный оператор, выполняю его и получаю ResultSet обратно.

Этот набор результатов я возвращаю вызывающей стороне.

Соединение и подготовленный оператор должны оставаться открытыми, пока вызывающая сторона не будет готова с этим возвращенным набором результатов

public DbResult insert(int cache, String shema, String table, LinkedHashMap<String, Object> 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;

    }


}

Вот мой класс DbResult

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
    }

В своем методе вставки я добавил, что try catch, потому что если что-то не получается, я должен закрыть ресурсы.

Если проблем нет,Я добавляю ресурсы к своему DbResult объекту, и там я закрываю ресурсы с помощью close() -метода.При этом я использую try-with, потому что если в этой цепочке одно закрытие завершается неудачно, то другие все еще закрываются, и исключение корректно пересылается.

У моего вызывающего абонента я также использую try-with, который вызывает этот close() -метод в DbResult после того, как я закончу с результатом.

Но это много кода, особенно конструкция try-catch в моем методе вставки.

Я не уверен, есть ли более простой или лучший способ сделать это.

У меня есть еще один вопрос:

Я мог бы кешировать результат, поэтому у меня нетпозаботиться о закрытии этого ресурса за пределами моего DatabaseHelper класса.

Существует CachedRowSet.Но я не уверен, насколько это дорого.Копирует ли это также метаинформацию?

Я думаю, нормальный ResultSet сначала получает данные, если я к ним обращаюсь: метаданные, данные строки: строка за строкой?

что это хорошая идея для кэширования данных в ArrayList из Hashmaps?

Arraylist -> Rows
HashMap -> столбцы по имени -> значение

Так что, если я сделаю это, я могу закрытьвсе ресурсы немедленно.
-> Мне не нужно заботиться о том, что закрытие за пределами моего DatabaseClass
-> пул восстанавливает соединение быстрее

Однако, возможно, я получаю данные, которые яне нужны (например, метаданные).

Кроме того, копировать мои данные в конструкцию ArrayList-> Hashmap дорого.

Итак, какие у вас есть идеи?того, что;какая лучшая практика?

...