Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
带有PreparedStatement的Java多线程和连接池_Java_Multithreading_Prepared Statement_Connection Pooling_C3p0 - Fatal编程技术网

带有PreparedStatement的Java多线程和连接池

带有PreparedStatement的Java多线程和连接池,java,multithreading,prepared-statement,connection-pooling,c3p0,Java,Multithreading,Prepared Statement,Connection Pooling,C3p0,我目前有一个数据库类,带有在构造函数中初始化的PreparedStatement成员变量。大概是这样的: public class Database { private Connection connection; private PreparedStatement statement1, statement2, ...; public Database(String url, String user, String pass) { Class.

我目前有一个数据库类,带有在构造函数中初始化的PreparedStatement成员变量。大概是这样的:

public class Database
{
    private Connection connection;
    private PreparedStatement statement1, statement2, ...;

    public Database(String url, String user, String pass)
    {
        Class.forName("com.mysql.jdbc.Driver").newInstance();
        connection = DriverManager.getConnection(url, user, pass);

        statement1 = connection.prepareStatement("sql stuff");
        statement2 = connection.prepareStatement("sql stuff");
        // etc
    }

    public User getUser(int userId)
    {
        // execute getUser statement
    }
    // and other similar methods
}
该应用程序将是多线程的,我想使用c3p0进行连接池。但我不知道该怎么做

假设我为每个线程创建一个数据库对象,构造函数现在从池中获得一个连接。每个线程应该只调用其中一个方法(最多5个查询),然后结束。我每次都要初始化所有准备好的语句吗?如果是的话,会不会花太长时间


有更好的方法吗?

您需要使用提供连接池的数据源,然后应用程序从池中获取连接

您可以像在应用程序启动时那样通过编程方式创建数据源,也可以从Web服务器控制台(取决于Web服务器)进行配置,然后通过JNDI在应用程序中获取数据源


预编译和对准备好的语句进行DB端缓存可以加快执行速度,并能够重用相同的SQL语句。

连接池的优点之一是它可以重用现有的连接,而您当前的实现无法做到这一点。因此,问题“每次初始化所有准备好的语句不会花费太长时间吗?”实际上并不相关,因为每次创建新的数据库连接很可能比每次初始化准备好的语句花费更长的时间。即使准备好的语句每次都被初始化并且从未被重复使用,我怀疑您是否会注意到任何性能差异,因为执行数据库语句比初始化准备好的语句花费的时间要长得多


也就是说,大多数JDBC驱动程序都可以选择缓存准备好的语句(也就是说,这并不完全取决于连接池)。例如,请参见MySQL配置选项(
cacheprepsmts
prepsmtcachesize
prepsmtcachesqllimit
)。但请记住,这些优化“很好”,首先要确保您的程序在多线程场景中正常工作(例如,确保始终将从池借用的连接返回到池,即使发生(运行时)异常),并且是正确的

我不知道c3p0是否支持语句缓存,但有一些池支持。例如,这个问题。有了这样的池,您可以重用准备语句的代码。如果像它这样的语句已经被缓存,缓存的副本将被返回,而不会产生实际准备语句的成本。这是否意味着如果我在一个连接中准备语句,而另一个线程稍后从池中获得另一个连接,那么这些语句就已经准备好了?或者他们必须为池中的每个连接都准备一次吗?我认为问题在于准备一份声明的成本以及如何避免。不是如何使用连接池。他问
我想使用c3p0进行连接池。但我不知道该怎么做。
但我还要澄清第二部分,因为我知道如何使用数据源。问题在于如何组织它,以便多个线程可以使用它,而不需要花费太长的语句时间。@dluga过长取决于数据库返回数据的方式。