Postgres中的COPY FROM和C3PO连接池

时间:2013-01-26 17:55:45

标签: java postgresql jdbc c3p0

我的JAVA程序中有以下代码,允许我将文件中的数据复制到Postgres数据库中:

Connection con = DriverManager.getConnection("jdbc:postgresql://localhost:####/myDb", 
                                                   "myuser", "mypassword"); 
CopyManager cm = new CopyManager((BaseConnection) con);
cm.copyIn("COPY prices FROM STDIN WITH DELIMITER AS ','", 
             new BufferedReader(new FileReader(filepath)), buffersize);

此代码工作正常,但我想使用连接池来管理我的连接,因为我有这个代码运行多个文件。所以我使用了C3P0

public static final ComboPooledDataSource cpds = new ComboPooledDataSource();

public class MyPooledConnection {
MyPooledConnection() throws PropertyVetoException {
    cpds.setDriverClass("org.postgresql.Driver"); 
    cpds.setJdbcUrl("jdbc:postgresql://localhost:5432/myStockDatabase"); 
    cpds.setUser("myUserName"); 
    cpds.setPassword("myPassword"); 
    cpds.setInitialPoolSize(4);
    cpds.setMinPoolSize(4);
    cpds.setMaxIdleTime(30);
    cpds.setMaxPoolSize(MAX_CONNECTIONS);
}

public static Connection getConnection() {
    return cpds.getConnection();
}
}

但是,当我从上面的连接池获得连接并尝试将其与CopyManager一起使用时,如下例所示,代码不起作用

Connection pooled_con = MyPooledConnection.getConnection();
CopyManager cm = new CopyManager((BaseConnection) pooled_con);
cm.copyIn("COPY prices FROM STDIN WITH DELIMITER AS ','", 
             new BufferedReader(new FileReader(filepath)), buffersize);

我猜这个问题与连接有关,但我似乎无法弄清楚它有什么不同。我尝试用SQLException和IOException捕获错误,但它也没有捕获。有没有人遇到过这个?

---- 修订版 ----

感谢a_horse_with_no_name对此的指导。以下代码对我有用

// Cast the connection as a proxy connection
C3P0ProxyConnection proxycon = (C3P0ProxyConnection)cpds.getConnection();
try {

    // Pass the getCopyAPI (from PGConnection) to a method
    Method m = PGConnection.class.getMethod("getCopyAPI", new Class[]{});
    Object[] arg = new Object[] {};

    // Call rawConnectionOperation, passing the method, the raw_connection, 
    // and method parameters, and then cast as CopyManager
    CopyManager cm = (CopyManager) proxycon.rawConnectionOperation(m,
                                         C3P0ProxyConnection.RAW_CONNECTION,arg);
    cm.copyIn("COPY prices FROM STDIN WITH DELIMITER AS ','", new BufferedReader(new 
                                                FileReader(filepath)), buffersize);
} catch (NoSuchMethodException | IllegalAccessException 
                        | IllegalArgumentException | InvocationTargetException e) {
    // Deal with errors here
}

2 个答案:

答案 0 :(得分:4)

游泳池没有给你"本地"连接,它总是发出一个代理对象:

从手册:

  

C3P0将这些对象包装在代理之后,因此您无法将C3P0返回的连接或语句强制转换为特定于供应商的实现类

您可能无法使用C3P0使用CopyManager。我不确定,但也许你可以使用这里描述的解决方法:http://www.mchange.com/projects/c3p0/#raw_connection_ops

如果这不起作用,您可能希望使用不同的连接池(例如新的Tomcat 7 JDBC-Pool),以便您访问基础本机连接。

答案 1 :(得分:0)

CopyManager cm = new CopyManager(cpds.getConnection().unwrap(PgConnection.class))

对我有用。