从 java.sql.Connection 创建线程安全的 MyBatis 会话

Creating thread safe MyBatis sessions from a java.sql.Connection

我正在尝试将 MyBatis 与 Snowflake 数据库一起使用。我的情况和楼主差不多:

Configure mybatis to use an existing connection

本质上,我可以获得一个 java.sql.Connection 对象,但我无法通过 DataSource 或通常由 RDBMS 数据库(如 Oracle)完成的其他步骤来获取它。一种建议的解决方案是做类似的事情 这个:

SqlSession snowflakeSession = snowflakeSqlSessionFactory.openSession(getSnowflakeConnection());

这些将在多线程环境中进行。如果有人关闭 snowflakeSession 对象,是否会关闭底层 java.sql.Connection 对象?我计划重新使用这些会话,但仅限于一个线程内。有这个必要吗?

对于 Oracle,我可以这样做:

        OracleDataSource result = new OracleDataSource();
        Class.forName("oracle.jdbc.driver.OracleDriver");
        String connectionString = jdbcUrl;
        String username = jdbcUserName; 
        String password = jdbcPassword;
        OracleDataSource oracleDataSource = (OracleDataSource)result; 
        oracleDataSource.setURL(connectionString);
        oracleDataSource.setPassword(password);
        oracleDataSource.setUser(username);
        String timeoutKey = "oracle.jdbc.ReadTimeout";
        Properties connectionProperties;
        try {
            connectionProperties = oracleDataSource.getConnectionProperties();
            if(connectionProperties==null) {
                connectionProperties = new Properties();
            }
            connectionProperties.put(timeoutKey, 60 /* minutes */ * 60 /* seconds per minutes */ * 1000 /* ms per seconds */);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return result;

如果我可以创建一个 SnowflakeDataSource 对象,我就可以像创建 Oracle 一样轻松地创建连接。我必须小心如何创建连接,因为这也是 MyBatis 扫描 XML 映射器文件或重新使用它已经从以前的连接请求中找到的内容的相同点。

调用DataSource::getConnection()时不出现to be documented but the Snowflake's JDBC Driver package does offer a basic DataSource class that can fetch entirely :

import net.snowflake.client.jdbc.SnowflakeBasicDataSource;

SnowflakeBasicDataSource ds = new SnowflakeBasicDataSource();

ds.setUrl("jdbc:snowflake://account.region.snowflakecomputing.com/");

ds.setUser("user");
ds.setPassword("password");
ds.setWarehouse("wh");
ds.setDatabaseName("db");
ds.setSchema("schema");
ds.setRole("role");

// Other arbitrary connection or session properties can be passed
// via URL params in the ds.setUrl(...) call above

// Use ds.setOauthToken(...)
// or  ds.setAuthenticator(...)
// or  ds.setPrivateKey(...)
// or  ds.setPrivateKeyFile(...)
// for alternative modes of authentication

Connection conn = ds.getConnection();