简体   繁体   English

缓存JDBC连接

[英]Cache JDBC connections

I have a small e-commerce application which relies heavliy on the database. 我有一个小型的电子商务应用程序,它依赖于数据库。 I've seen some performance issues with it, primary when it comes to establishing a connection to the database. 我已经看到了它的一些性能问题,主要是建立与数据库的连接。 I'm not a DBA, or any other deep DB knowledge - but I know that it makes sense to cache the connections instead of establishing a new one all the time. 我不是DBA,也不是任何其他深层数据库知识 - 但我知道缓存连接而不是一直建立新连接是有意义的。

Below is my method for getting the connection: 下面是我获取连接的方法:

public Connection getConnection() throws SQLException, ClassNotFoundException  {
    Class.forName("com.mysql.jdbc.Driver"); 
    con=DriverManager.getConnection("jdbc:mysql://182.31.456.32:3306/"+database+"",""+username+"",""+password+""); 
   // stm=con.createStatement(); 
    return con;
}

My question is - how can I easily cache a current connection and reuse it instead of creating a new one using JDBC/Java? 我的问题是 - 如何轻松缓存当前连接并重用它而不是使用JDBC / Java创建新连接?

Thanks. 谢谢。

In a situation where you have a pretty large e-commerce application , you don't usually code DB connection they way you show in your code. 在您拥有相当大的电子商务应用程序的情况下 ,您通常不会按照您在代码中显示的方式编写数据库连接。

We make use of connection pools. 我们使用连接池。

I guess, your e-commerce application would be deployed in some application server, use connection pool facility of that server to manage your database connections. 我想,您的电子商务应用程序将部署在某个应用程序服务器中,使用该服务器的连接池工具来管理您的数据库连接。

You can use one of connection pool APIs like C3P0 etc to explicitly code pooling functionality if its an application without a server. 如果没有服务器的应用程序,您可以使用其中一个连接池API(如C3P0等)显式编码池功能。

I guess the thing that you are calling a connection caching is basically to ask to implement a Singleton . 我猜你正在调用连接缓存的事情基本上是要求实现一个Singleton There would be lots of examples on Internet as how to implement a singleton but you shouldn't be closing connections in code then. 在Internet上会有很多关于如何实现单例的例子,但是你不应该在代码中关闭连接。

There is something called connection-timeout time, you need to set that properly if going with single connection caching solution. 有一种称为连接超时的时间,如果使用单连接缓存解决方案,则需要正确设置。

Hope it helps !! 希望能帮助到你 !!

What you need is a connection pool that you can easily configure out of the box in Tomcat , this way the connection pool will be managed directly by Tomcat which avoids a lot of integration issues, guarantees a full compatibility and avoids adding new dependencies. 你需要的是一个连接池 ,你可以很容易地配置出盒子的Tomcat ,这样的连接池将被直接管理Tomcat这避免了大量的集成问题,保证了全兼容性,同时避免增加新的依赖。

Here are the steps to follow: 以下是要遵循的步骤:

1. Define the connection pool globally 1.全局定义连接池

In conf/contex.xml you need to define your connection pool as Resource so for example in you case it could be something like that: conf/contex.xml您需要将连接池定义为Resource ,例如在您的情况下,它可能是这样的:

<Context>

    ...
    <Resource name="jdbc/myPool" auth="Container" type="javax.sql.DataSource"
                initialSize="5" maxActive="20" minIdle="5" maxIdle="15" maxWait="10000"
                validationQuery="SELECT 1" validationQueryTimeout="5"
                testWhileIdle="true" testOnBorrow="true" testOnReturn="false"
                timeBetweenEvictionRunsMillis="30000" minEvictableIdleTimeMillis="60000"
                removeAbandoned="true" removeAbandonedTimeout="300" logAbandoned="false"
                poolPreparedStatements="true"
                username="myUsername" password="myPassword"
                driverClassName="com.mysql.jdbc.Driver" 
                url="jdbc:mysql://182.31.456.32:3306/mydb?autoReconnect=true" />
</Context>

2. Declare your connection pool for your webapp 2.为您的webapp声明连接池

In the web.xml of your webapp, you need to define it locally using a resource-ref as next: 在webapp的web.xml中,您需要使用resource-ref在本地定义它,如下所示:

<web-app>
    ...
    <resource-ref>
        <res-ref-name>jdbc/myPool</res-ref-name>
        <res-type>javax.sql.DataSource</res-type>
        <res-auth>Container</res-auth>
    </resource-ref>
    ...
</web-app>

3. Access to my datasource from my code 3.从我的代码访问我的数据源

You can then access to your DataSource using JNDI 然后,您可以使用JNDI访问您的DataSource

Context initContext = new InitialContext();
Context envContext  = (Context)initContext.lookup("java:/comp/env");
DataSource ds = (DataSource)envContext.lookup("jdbc/myPool");
Connection conn = ds.getConnection();

4. Deploy your JDBC driver 4.部署JDBC驱动程序

Your JDBC driver needs to be available in the Common ClassLoader of Tomcat as it is a global resource, such that you need to put the jar of your driver in tomcat/lib 您的JDBC驱动程序需要在Tomcat的Common ClassLoader中可用,因为它是一个全局资源,因此您需要将驱动程序的jar放在tomcat/lib


More details about JNDI Datasource in Tomcat here 有关Tomcat JNDI数据源的更多详细信息,请参见此处

You could use a singleton class like the one below: 您可以使用如下所示的单例类:

public class DBHandler{

    private static Connection conn = null;

    private DBHandler(String connString){
        Class.forName("com.mysql.jdbc.Driver"); 
        conn=DriverManager.getConnection(connString);    
    }

    public static void getConnection(String connString) {
        if (conn == null)
            new DBHandler(String connString);
        return conn;
    }
}

It will create the connection during the first DBHandler.getConnection() call and caches it in the conn field. 它将在第一个DBHandler.getConnection()调用期间创建连接,并将其缓存在conn字段中。 Later DBHandler.getConnection() calls will return this cached connection. 稍后DBHandler.getConnection()调用将返回此缓存连接。

If your application needs to handle a lot of DB requests,please read about Connection Pooling as well. 如果您的应用程序需要处理大量数据库请求,请阅读有关连接池的信息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM