Тема уже обсуждалась в некоторых предыдущих вопросах. Новые элементы приходят с новыми проблемами. Я ищу здесь лучший способ обработки соединений с базой данных, касающихся следующих аспектов: ремонтопригодность , производительность , безопасность и реализация . Должен отметить, что в настоящее время я не заинтересован в таких абстракциях, как Hibernate, Spring и т. Д. Вот факты:
Сценарий 1 - шаблон синглтона
Основные идеи здесь: проверить детали подключения, создать экземпляр подключения, написать для нее статический метод получения и использовать его столько времени, сколько необходимо. Пример кода:
static Connection connection;
private Statement stmt = null;
connection = createConnection(...)
stmt = connection.createStatement();
Запросы будут выполняться с использованием:
stmt.execute();
Теперь, это может показаться не слишком причудливым, но ... это работает. У меня есть полный контроль над моим соединением, его закрытие, создание экземпляра, закрытие resultSet (должно выполняться каждым вызывающим абонентом) и т. Д.
Сценарий 2 - шаблон Singleton с PreparedStatement
Как некоторые люди предложили здесь, я ввел PreparedStatement для выполнения запросов, и в основном я удалил переменную stmt , и вместо этого я использую выражение:
PreparedStatement pStmt= getConnection().prepareStatement(query);
pStmt.execute();
Используя анализатор кода PMD, я заметил, что pSmt может не закрыться, что действительно так, потому что я не могу закрыть его здесь и не могу дать команду вызывающей стороне закрыть его. Такой подход приводит к следующему сценарию.
Сценарий 3 - шаблон Singleton со статическим PreparedStatement
Все готово, я объявил:
private static PreparedStatement preparedStmt = null;
Мой метод executeQuery () адаптируется к:
setPreparedStmt(getConnection().prepareStatement(query));
getPreparedStmt().execute();
где установщик и получатель просто .. установщики и получатели, с общедоступной видимостью и статическим атрибутом.
Этот подход легко понять, и вызывающие абоненты должны будут сами закрывать PreparedStatement
(нет проблем, но закрытие PreparedStatement
также закроет ResultSet
, если это так?). Однако почему-то я чувствую, что повторное использование этого предварительно скомпилированного оператора не так уж и безопасно с транзакционным аспектом базы данных. Здесь есть какие-нибудь опасности?
Сценарий 4 - Использование пула соединений
Этот аспект требует дальнейшего изучения, но я понял основную идею. Я не могу вдаваться в подробности об этой практике, но здесь также есть несколько вопросов:
4.1 Я знаю, что можно установить количество подключений, максимальный размер пула. Например, каким будет это число для одного пользователя, в результате я умножу это число на количество пользователей.
4.2 Используя пул соединений, должен ли я использовать Statement
или PreparedStatement
при получении одного соединения из пула и использовать его для выполнения какого-либо запроса?
4.3 Насколько я понимаю, используя эту стратегию, я должен закрыть соединение после того, как его задача будет выполнена. Но что, если по каким-то причинам соединение не может быть закрыто? Если по какой-то причине это повторится несколько раз, равный размеру пула соединений, мы обречены.
ОК, я остановлюсь здесь, возможно, последуют некоторые обновления, в зависимости от ответов. Мэнни, спасибо.