从连接池获取数据库连接

Mar*_*ada 11 java jsp servlets

我正在重构其他代码.我注意到的一件事是关于系统如何从连接池获得连接的方式.

样品是这样的.在每次调用服务方法时,系统都会在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();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我确实认为每次这样做都会影响性能.我正在考虑另外一种方法来解决如何从连接池中检索连接.

我正在考虑使用servlet的init()方法,但我认为这不是最佳的.

Bal*_*usC 15

在做一次就可以ServletContextListener的,而不是每次init()许多的servlet.该contextInitialized()方法仅在webapp启动期间执行一次.

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

在以下位置配置如下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>
Run Code Online (Sandbox Code Playgroud)

您可以在servlet中获取它,如下所示(init()doXXX()您选择的方法):

DataSource dataSource = Config.getInstance(getServletContext()).getDataSource();
Run Code Online (Sandbox Code Playgroud)

然而,我会进一步重构它,JDBC代码最好放在它自己的类中,而不是放在servlet中.查找DAO模式.

  • @robert:你绝对不应该保持连接打开那么长时间.你需要根据普通的JDBC习惯用自己关闭它:在`try`块的`finally`块中打开它.请注意`DataSource!= Connection`.另见这个答案:http://stackoverflow.com/questions/2313197/jdbc-mysql-connection-pooling-practices/2313262#2313262将来,如果您有疑问,请按"提问",我们应该得分:) (3认同)