Как подключиться к базе данных JDBC / источнику данных в приложении на основе сервлета?

17

У меня есть внешний MySQL-сервер, который настроен и работает нормально. Я создал соединение с базой данных в Eclipse и может просматривать базу данных на вкладке «Проводник источника данных».

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

Также, как лучше всего открыть соединение? У меня есть файл mysql-connector-java-5.1.11-bin.jar , и я нашел два метода, которые работают:

MysqlDataSource d = new MysqlDataSource();
d.setUser("user");
d.setPassword("pass");
d.setServerName("hostname.com");
d.setDatabaseName("db");
Connection c = d.getConnection();

и

Connection c = DriverManager.getConnection("jdbc:mysql://hostname.com/db","user","pass");

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

    
задан Ed Marty 19.02.2010 в 21:52
источник

2 ответа

39

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

Если вы используете Tomcat в качестве servletcontainer, вам необходимо настроить источник данных в соответствии с его Документация JNDI . Вы увидите, что есть несколько способов. Самый простой способ - создать /META-INF/context.xml в webcontent вашего динамического веб-проекта (чтобы быть понятным, /META-INF находится на том же уровне, что и /WEB-INF от webapp) и заполнить его чем-то вроде:

<?xml version="1.0" encoding="UTF-8"?>

<Context>
    <Resource
        name="jdbc/db" type="javax.sql.DataSource"
        maxActive="100" maxIdle="30" maxWait="10000" 
        url="jdbc:mysql://hostname.com/db"
        driverClassName="com.mysql.jdbc.Driver"
        username="user" password="pass"
    />
</Context>

Это означает, что сервер Tomcat должен создавать источник данных с именем JNDI jdbc/db с максимально 100 активными соединениями, максимум 30 незанятых соединений и максимальным временем ожидания 10000 миллисекунд до соединение должно быть возвращено из вашего приложения (фактически: закрыто вашим приложением, поэтому ваше приложение имеет 10 секунд времени между приобретением соединения и закрытием соединения). Остальные настройки должны быть знакомы и достаточно объяснять вам; это настройки JDBC.

Наконец, в своем веб-проекте отредактируйте файл /WEB-INF/web.xml , чтобы добавить следующую запись:

<resource-env-ref>
    <resource-env-ref-name>jdbc/db</resource-env-ref-name>
    <resource-env-ref-type>javax.sql.DataSource</resource-env-ref-type>
</resource-env-ref>

Это примерно означает, что веб-приложение должно использовать предоставленный сервером источник данных с именем jdbc/db .

Затем измените свой диспетчер подключений на что-то вроде этого:

private DataSource dataSource;

public Database(String jndiname) {
    try {
        dataSource = (DataSource) new InitialContext().lookup("java:comp/env/" + jndiname);
    } catch (NamingException e) {
        // Handle error that it's not configured in JNDI.
        throw new IllegalStateException(jndiname + " is missing in JNDI!", e);
    }
}

public Connection getConnection() {
    return dataSource.getConnection();
}

.. и замените все Class.forName(driver) вызовов new Database("jdbc/db") и замените все DriverManager.getConnection() на database.getConnection() . Вы можете при необходимости получить значение jdbc/db из некоторого файла конфигурации ( файла свойств? ).

В качестве альтернативы добавьте DataSource с помощью @Resource аннотации внутри артефакта, управляемого контейнером, например @WebServlet класса сервлета

@Resource("jdbc/db")
private DataSource dataSource;

Это должно быть так. Просто разверните веб-приложение с указанными выше изменениями и запустите его. Не забудьте поместить драйвер JDBC базы данных в Tomcat/lib или добавить свой путь к свойству shared.loader Tomcat/conf/catalina.properties , потому что ответственность за загрузку драйвера JDBC теперь перемещена из веб-приложения на сервер. Для получения дополнительных советов и других основных примеров JDBC / JNDI вы можете найти эту статью полезную также.

См. также:

ответ дан BalusC 19.02.2010 в 22:53
источник
  • Это выглядит очень полезно. Еще два вопроса. 1: Я не знаю, это ли это только я, или это нормально, но нет каталога tomcat / lib, есть несколько каталогов lib в общих / lib, server / lib и shared / lib. На что должна входить моя банка? И вопрос 2: Будет ли это обрабатывать объединение пулов, как оно установлено здесь? Должен ли я вызвать close () в соединении, возвращенном из getConnection () после каждого использования? –  Ed Marty 19.02.2010 в 23:20
  • 1) Вы, очевидно, используете 6 ~ 8-летний Tomcat 5.x. Обновите Tomcat 6.0, если сможете (настоятельно рекомендую) или захватить Tomcat 5.x's / shared / lib. 2) Да, он будет обрабатывать пул соединений. И да, вы должны ВСЕГДА называть close () в конце. Реализация пула соединений сама по себе беспокоится о закрытии или выпуске. Также проверьте последнюю главу последней ссылки. –  BalusC 20.02.2010 в 00:34
  • @BalusC У меня вопрос, хотя пост немного устарел. Есть ли способ сделать пароль зашифрованным? В контексте.xml пароль - это чистый текст, так что так или иначе, чтобы интегрировать создание источника данных с веб-приложением в Eclipse? –  user75ponic 23.02.2012 в 11:04
  • для tomcat 7, это должно быть <resource-ref> <description> MySQL Datasource </description> <res-ref-name> jdbc / db </res-ref-name> <res-type> javax.sql .DataSource </res-type> <res-auth> Контейнер </res-auth> </resource-ref> –  xhe8 16.12.2016 в 20:45
3

Вы можете настроить источник данных на любом сервере приложений, на котором развертывается WAR, и получить ссылку на него с помощью JNDI. Или вы можете упаковать свою WAR в EAR и определить источник данных в файле data-sources.xml EAR (и получить ссылку на него с помощью JNDI).

    
ответ дан Voytek Jarnot 19.02.2010 в 22:10
источник