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

У меня есть внешний сервер 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, так что есть хорошее место для размещения данных соединения? Или есть способ отказаться от всего этого и просто использовать соединение в проводнике источника данных?

Ответы

Ответ 1

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

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

<?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 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(name="jdbc/db")
private DataSource dataSource;

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

Смотрите также:

Ответ 2

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