Лучший способ для многих классов ссылаться на класс соединения с базой данных - PullRequest
2 голосов
/ 12 марта 2009

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

Что я хочу знать, так это лучший способ узнать эти ссылки о классе базы данных? Мой инстинкт состоял бы в том, чтобы сделать методы в классе Database статичными и вызвать их как Database.method (), но есть ли лучший способ?

P.S. Правильно ли было слово для этого? Если не то, что нужно, то в следующий раз у меня будет похожий вопрос.

Ответы [ 6 ]

7 голосов
/ 12 марта 2009

Будьте осторожны.

Синглтон будет узким местом.

java.sql.Connection НЕ является потокобезопасным, поэтому вы можете столкнуться с проблемами там.

Я бы рекомендовал написать ваше приложение с разделенными слоями обслуживания и постоянства. Оба должны быть основаны на интерфейсах. Сервисный уровень - это тот, который знает об единицах работы и транзакциях, используя для этого модели и объекты персистентности. Служба должна отвечать за получение соединения, делая его доступным для уровня постоянства, обрабатывая транзакции и закрывая соединение в той же области действия метода, в которой оно было создано.

Область применения и очистка являются ключевыми. Если вы этого не сделаете, вы исчерпаете соединения с базой данных.

Вы не упоминаете пулы соединений. Я бы порекомендовал один.

Посмотрите на весну. Его модуль JDBC прекрасно справляется со всем этим. Если вы не можете использовать Spring для своего задания, по крайней мере, это будет хорошей моделью для разработки вашей реализации.

4 голосов
/ 12 марта 2009

Традиционный подход заключается в создании DAO (объекта доступа к данным) для каждого класса данных.

т.е. если у вас есть класс данных "Person", у вас также есть класс "PersonDAO", который реализует такие методы, как findById (), findAll (), save (Person) и т. д. В основном класс DAO обрабатывает все взаимодействия с БД.

Конструктор класса DAO может просто принять объект Connection и, таким образом, перенести проблему создания соединений на другой уровень или вызвать метод фабрики где-нибудь, который выделил объект Connection.

В любом случае вам, скорее всего, понадобится такой фабричный метод.

public class Database{
   public static Connection getConnection(){
      // Create a new connection or use some connection pooling library 
   }
}

Как кто-то отметил, java.sql.Connection не является потокобезопасным, поэтому вам не следует каждый раз передавать одно и то же соединение, если вы не уверены, что несколько потоков не будут обращаться к методу.

Конечно, если вам нужно создать новое соединение для каждого звонка, вам также нужно будет закрыть соединения, как только вы закончите с ними. Простой подход состоит в том, чтобы добавить метод close () в DAO и заставить их позаботиться об этом. Это накладывает бремя на код, использующий DAO.

Даже если вы используете пул соединений, все равно необходимо закрыть соединения (вернуться в пул), как только вы закончите с ними.

Кто-то предложил использовать локальный поток для подключения к каждому потоку. В некоторых случаях это работает, но не будет полезно для веб-приложения, где каждый запрос является новым потоком (который никогда не используется повторно, а также может не хранить ссылку).

Однако вы можете воспользоваться этим в веб-приложении, если вы настроили его так, чтобы после обработки каждого запроса вызывался вызов Database.closeConnection (), который затем позаботился о закрытии локального соединения Tread, если оно существует.

1 голос
/ 12 марта 2009

Избегайте чего-либо статичного. Предпочитают «Параметризация сверху» .

Итак, вы хотите создать объект-обертку базы данных рядом с вашим 'main'. Затем передайте это в качестве аргумента конструктора объектам, которые в этом нуждаются.

0 голосов
/ 12 марта 2009

Если вы хотите хранить соединение статически, хотя бы используйте локальный поток. Но, как говорили здесь другие, лучше вводить соединение или его обертку в объекты, которые должны его использовать.

0 голосов
/ 12 марта 2009

Если вы пойдете так, как вы предлагали, вам будет сложно тестировать свои классы. Один из способов - передать информацию о вашей базе данных классам, выполняющим запрос, например,

Query query = new GetPersonQuery(Database database);
query.run(); // or whatever

Это будет особенно хорошо работать, если вы используете шаблон DAO, поэтому:

PersonDao dao = new PersonDao(Database database);
dao.findAll();

База данных может затем обернуть все, что вам нужно, например, Пул соединений, кеширование и т. Д.

0 голосов
/ 12 марта 2009

Шаблон Singleton поможет вам в этом. См. подробнее об этом здесь.

Шаблон (справедливо) здесь очень не нравится, потому что он по сути делает глобальный набор методов, которых следует избегать в объектно-ориентированном мире - но для курсовой работы и для того, чего вы пытаетесь достичь может быть проще всего.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...