首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从连接池获取数据库连接

从连接池获取数据库连接
EN

Stack Overflow用户
提问于 2010-12-21 00:25:59
回答 4查看 19.8K关注 0票数 11

我正在重构别人的代码。我注意到的一件事是系统如何从连接池获取连接的方式。

示例是这样的。每次调用服务方法时,系统都会在数据源的JNDI上进行上下文查找。

代码语言:javascript
复制
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();
        }
    }
}

我确实认为每次这样做都会影响性能。关于如何从连接池中检索连接,我正在考虑另一种方法。

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

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2010-12-21 01:21:51

ServletContextListener中做一次,而不是在许多servlet的init()中每次都做。在webapp启动期间,contextInitialized()方法只执行一次。

代码语言:javascript
复制
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中按如下方式进行配置

代码语言:javascript
复制
<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>

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

代码语言:javascript
复制
DataSource dataSource = Config.getInstance(getServletContext()).getDataSource();

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

票数 15
EN

Stack Overflow用户

发布于 2010-12-21 00:44:28

我在过去使用的方法是创建一个包含数据源的单例类

例如。

代码语言:javascript
复制
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查找开销。

票数 3
EN

Stack Overflow用户

发布于 2013-02-08 17:53:04

我只是用它做了一些测试,发现jndi查找时间并不是很重。在这里,在大约1秒内进行50.000次查找。

所以在很多情况下,我根本看不到缓存DataSource的理由。

缓存的问题是,您可能会得到一个陈旧的DataSource,如果您更改了与数据源定义相关的任何内容,则会迫使您重新启动应用程序。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4491596

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档