Получить соединение с базой данных из пула соединений - PullRequest
11 голосов
/ 20 декабря 2010

Я рефакторинг чужого кода.Единственное, что я замечаю, это то, как система получает соединение из пула соединений.

Пример подобен этому.При каждом вызове метода службы система выполняет поиск контекста в JNDI для источника данных.

public class CheckinServlet extends HttpServlet {

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        try {
            //Obtain Connection
            InitialContext initialContext = new InitialContext();
            javax.sql.DataSource ds = (javax.sql.DataSource) initialContext
                    .lookup("jdbc/mysqldb");
            java.sql.Connection conn = ds.getConnection();
            //business logic
            //redirect
        } finally {
            conn.close();
        }
    }
}

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

Я думаю об использовании метода сервлета init(), но я думаю, что он не оптимален.

Ответы [ 4 ]

15 голосов
/ 20 декабря 2010

Делайте это один раз в ServletContextListener вместо каждого раза в init() многих сервлетов. Метод contextInitialized() выполняется только один раз при запуске веб-приложения.

public class Config implements ServletContextListener {
    private static final String ATTRIBUTE_NAME = "config";
    private DataSource dataSource;

    @Override
    public void contextInitialized(ServletContextEvent event) {
        ServletContext servletContext = event.getServletContext();
        String databaseName = servletContext.getInitParameter("database.name");
        try {
            dataSource = (DataSource) new InitialContext().lookup(databaseName);
        } catch (NamingException e) {
            throw new RuntimeException("Config failed: datasource not found", e);
        }
        servletContext.setAttribute(ATTRIBUTE_NAME, this);
    }

    @Override
    public void contextDestroyed(ServletContextEvent event) {
        // NOOP.
    }

    public DataSource getDataSource() {
        return dataSource;
    }

    public static Config getInstance(ServletContext servletContext) {
        return (Config) servletContext.getAttribute(ATTRIBUTE_NAME);
    }
}

Настройте его следующим образом в web.xml:

<context-param>
    <param-name>database.name</param-name>
    <param-value>jdbc/mysqldb</param-value>
</context-param>
<listener>
    <listener-class>com.example.Config</listener-class>
</listener>

Вы можете получить его в своем сервлете следующим образом (вы выбираете метод init() или doXXX()):

DataSource dataSource = Config.getInstance(getServletContext()).getDataSource();

Однако я бы сделал рефакторинг еще на шаг, код JDBC желательно размещать в его собственных классах, а не в сервлетах. Поиск шаблона DAO.

3 голосов
/ 08 февраля 2013

Я только что провел некоторое тестирование с этим и обнаружил, что время поиска jndi не так уж и много. 50 000 просмотров за 1 секунду здесь.

Так что во многих случаях я вообще не вижу причин для кэширования источника данных.

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

3 голосов
/ 20 декабря 2010

Метод, который я использовал в прошлом, заключается в создании одноэлементного класса, который содержит источник данных

* 1003 Е.Г. *

public class DatabaseConnectionManager {

    DataSource ds;

    public void init() {
        InitialContext initialContext = new InitialContext();
        ds = (javax.sql.DataSource)initialContext.lookup("jdbc/mysqldb");
    }

    public Connection getConnection() {
        if(ds == null) init();

        return ds.getConnection();
    }
}

Это означает, что у вас есть общая ссылка на ваш источник данных, что исключает накладные расходы на поиск jndi.

2 голосов
/ 20 декабря 2010

В добавление к сказанному, существует шаблон проектирования под названием Service Locator , который в основном представляет собой синглтон, содержащий реестр, называемый "service", в котором хранятся ваши объекты JNDI.объект не найден в реестре, служба взята из пула JNDI и зарегистрирована в реестре.Следующий вызов просто извлечет объект из реестра.

Надеюсь, это поможет.

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