如何手动创建和配置MariaDBDataSource

时间:2016-03-24 12:05:49

标签: java jdbc mariadb

我在使用MariaDBDataSource类创建非池化数据源时遇到问题。

MariaDbDataSource mysqlDs = new MariaDbDataSource(connectionUrl);
mysqlDs.setPassword(password);
mysqlDs.setUser(username);
return wrapWithPool(mysqlDs);

wrapWithPool只是用给定的数据源(c3p0池)包装给定的数据源。 但我无法从池中检出连接。每当我做的时候

datasource.getConnection()

我得到了

org.mariadb.jdbc.internal.util.dao.QueryException: Could not connect: Access denied for user 'someuser'@'somehost' (using password: NO)

不确定为什么?我设置非空密码。还有什么可以在MariaDbDatasource类上设置以使其使用密码吗?

编辑: 好的,所以看来当我不包装MariaDbDataSource时一切正常。 所以c3p0打破了连接,从调试我发现它无法获得密码...... 包装方法非常简单

private static DataSource wrapWithPool(DataSource unpooled) throws SQLException {
            unpooled.setLoginTimeout(HOST_REACH_TIMEOUT.getValue());
            Map<String, Object> poolOverrideProps = new HashMap<>();
            poolOverrideProps.put("maxPoolSize", CONNECTION_POOL_SIZE.getValue());
            poolOverrideProps.put("minPoolSize", 1);
            poolOverrideProps.put("checkoutTimeout", HOST_REACH_TIMEOUT.getValue() * 2);
            return DataSources.pooledDataSource(unpooled, poolOverrideProps);

        }

它与其他驱动程序(oracle,jtds)完美配合。为什么不用mariaDb?

1 个答案:

答案 0 :(得分:0)

好的,所以我发现了这个问题。出于某种原因,创建池时c3p0将给定的DataSource类包装在自己的WrapperConnectionPoolDataSourceBase类中。然后它尝试使用反射从中检测身份验证参数。由于MariaDBDataSource不提供getPassword方法,因此发现的值为null,因此显示有关不使用密码的错误消息。

作为一种解决方法,我做了一个简单的包装器

private static class MariaDbDExtender extends MariaDbDataSource {

        private String password;

        public MariaDbDExtender(String connectionUrl) throws SQLException {
            super(connectionUrl);
        }


        @Override
        public void setPassword(String pass) {
            this.password = pass;
            super.setPassword(pass);
        }

        //this method is required to allow c3p0 magically use reflection to get correct password for connection
        public String getPassword() {
            return password;
        }
    }

以及稍后

MariaDbDExtender mysqlDs = new MariaDbDExtender(connectionUrl);
mysqlDs.setPassword(password);
mysqlDs.setUser(username);
return wrapWithPool(mysqlDs);

它神奇地开始工作。这是一些特定于驱动程序的问题,因为oracle数据源没有getPassword方法,但有效。因此,这两个库的一些非常具体的实现细节只会使它在我的用例中不兼容。