Как мне управлять подключением к базе данных с помощью Java-сервлетов, JSP и Tomcat? - PullRequest
2 голосов
/ 11 сентября 2010

Я довольно плохо знаком с сервлетами и JSP, а также с базами данных.

На данный момент у меня есть класс в части «модель» моего веб-приложения, в котором есть множество методов, которые я написал для выполнения запросов и обновлений базы данных. На данный момент в каждом из этих методов я создаю соединение с базой данных, выполняю SQL-запросы, затем закрываю соединение.

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

В Head First Servlet & JSP от Basham, Sierra & Bates они описывают, как можно использовать реализацию ServletContextListener для создания объекта при развертывании веб-приложения, который будет добавлен в качестве атрибута ServletContext. Авторы не углубляются в это, но подразумевают, что люди часто добавляют соединение с базой данных в качестве атрибута ServletContext. Я думал, что хотел бы реализовать это для себя, но после прочтения этой статьи stackoverflow по управлению подключением к базе данных Я не так уверен.

Однако, поскольку я только начинаю с сервлетов и JSP, не говоря уже об остальной части J2EE, большая часть этой статьи мне не подходит.

Что выделяет меня из этой статьи:

  • Что-то может случиться, чтобы разорвать это соединение с базой данных, и если мы полагаемся только на это соединение, то нам нужно будет повторно развернуть наше приложение, чтобы перезапустить соединение. это правильно?

  • Мы должны ответить на контейнере, чтобы управлять соединениями с базой данных для нас. Отлично, но как это достигнуто? Как я могу общаться с контейнером? (Пожалуйста, имейте в виду, что я только начал с сервлетами и JSP).

  • С точки зрения дизайна сервлета в целом, у меня есть один класс сервлетов для каждого типа запроса, который обычно имеет только один тип вызова базы данных, то есть конкретное обновление или запрос. Вместо того, чтобы иметь класс со всеми методами для запросов к базе данных, лучше ли мне иметь методы в своих соответствующих сервлетах или это будет противоречить шаблону Model-View-Controller?

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

Большое спасибо заранее за ваши комментарии

Джо

Ответы [ 4 ]

2 голосов
/ 11 сентября 2010

На следующей странице веб-сайта Tomcat подробно описывается, как подключить Tomcat и mySQL. Вы не хотите создавать свои собственные, слишком много уже доступных пулов источников данных, которые были отлажены и опробованы в производственных средах.

Главное в использовании пула состоит в том, что соединение не прерывается при вызове close, а просто возвращается в пул. Поэтому важно убедиться, что вы закрываете свои ресурсы в блоке try / finally. Ищите здесь образец .

1 голос
/ 11 сентября 2010

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

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

Существует несколько отдельных реализаций пула соединений (C3P0, Commons DBCP, Bone CP), которые вы можете объединить в своем приложении. Но при использовании контейнера сервлетов или Java EE я бы использовал пул соединений, предоставляемый контейнером. Затем получите DataSource (дескриптор пула соединений) через JNDI из приложения, чтобы получить от него соединение JDBC (и закройте его, чтобы вернуть его в пул).

Способ настройки пула, очевидно, зависит от конкретного контейнера, поэтому вам нужно обратиться к документации вашего контейнера. Хорошей новостью является то, что Tomcat предоставляет несколько примеров , показывающих, как это сделать, как получить источник данных через JNDI и как написать правильный код JDBC (читайте до конца страницы).

Ссылки

1 голос
/ 11 сентября 2010

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

С точки зрения вашего кода, изменений очень мало.В основном:

  • Доступ к пулам соединений осуществляется через интерфейс DataSource, в то время как соединения без пула могут быть доступны через старый DriverManager.
  • . Чтобы получить DataSource, выобычно приходится использовать JNDI, поскольку это стандартный метод публикации пулов соединений в приложении J2EE.
  • Вы хотите close() Connection объекты как можно скорее.Это возвращает соединение с пулом без отключения от БД, так что другие потоки могут его использовать.

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

Это пример кода из http://download.oracle.com/javase/1.4.2/docs/guide/jdbc/getstart/datasource.html (ПРИМЕЧАНИЕ: не исключение-сейф ).Как видите, как только вы получите ссылку Connection, ничего особенного не будет.

Context ctx = new InitialContext();
DataSource ds = (DataSource)ctx.lookup("jdbc/AcmeDB");
Connection con = ds.getConnection("genius", "abracadabra");
con.setAutoCommit(false);
PreparedStatement pstmt = con.prepareStatement(
                            "SELECT NAME, TITLE FROM PERSONNEL WHERE DEPT = ?");
pstmt.setString(1, "SALES");
ResultSet rs = pstmt.executeQuery();

System.out.println("Sales Department:");
while (rs.next()) {
        String name = rs.getString("NAME");
        String title = rs.getString("TITLE");
        System.out.println(name + "  ; ;" + title);
}
pstmt.setString(1, "CUST_SERVICE");
ResultSet rs = pstmt.executeQuery();

System.out.println("Customer Service Department:");
while (rs.next()) {
        String name = rs.getString("NAME");
        String title = rs.getString("TITLE");
        System.out.println(name + "  ; ;" + title);
}
rs.close();
pstmt.close();
con.close();
1 голос
/ 11 сентября 2010

Я хотел бы проверить пул соединений и, в частности, такие фреймворки, как C3P0 или Apache Commons DBCP .

Оба этих пакета будут следить за поддержанием и управлением коллекцией соединений с базой данных для вас.

Обычно соединения устанавливаются заранее и передаются запрашивающим потокам по мере их необходимости. Соединения могут быть проверены до раздачи (и переделаны заранее клиентом, использующим их, если соединение разорвано).

...