聊聊 Mybatis 的数据源之获取连接
看完 PooledDataSource 的 pushConnection()方法,再看一下它的 popConnection()方法:
获取数据库连接
获取数据库的连接调用 getConnection()方法:
     @Override    public Connection getConnection(String username, String password) throws SQLException {        return popConnection(username, password).getProxyConnection();    }
       复制代码
 popConnection()方法
然后分析一下 popConnection()方法:
代码虽然比较长,占篇幅,我在这里就不贴代码了,但是方法的逻辑还是比较理解的:
先从空闲连接集合中获取连接信息,如果空闲集合中没有并活跃的连接数没有达到上限的时候就可以创建新的数据库连接,如果达到上限了就判断是否有超时的连接,如果有的话就利用这个超时连接创建新的连接并把超级连接设置为无效,如果超时连接也没有,这时候就调用 wait 方法进行阻塞
检测连接是否可用
PooledConnection 的 isValid()方法用来检测数据库连接是否可用
 public boolean isValid() {        return valid && realConnection != null && dataSource.pingConnection(this);    }
       复制代码
 
看这个方法的实现代码,最终还是调用 PooledDataSource 的 pingConnection()方法
 protected boolean pingConnection(PooledConnection conn) {        boolean result = true; 
        try {            result = !conn.getRealConnection().isClosed();        } catch (SQLException e) {            if (log.isDebugEnabled()) {                log.debug("Connection " + conn.getRealHashCode() + " is BAD: " + e.getMessage());            }            result = false;        }
                if (result && poolPingEnabled && poolPingConnectionsNotUsedFor >= 0                && conn.getTimeElapsedSinceLastUse() > poolPingConnectionsNotUsedFor) {            try {                if (log.isDebugEnabled()) {                    log.debug("Testing connection " + conn.getRealHashCode() + " ...");                }                Connection realConn = conn.getRealConnection();                try (Statement statement = realConn.createStatement()) {                    statement.executeQuery(poolPingQuery).close();                }                if (!realConn.getAutoCommit()) {                    realConn.rollback();                }                result = true;                 if (log.isDebugEnabled()) {                    log.debug("Connection " + conn.getRealHashCode() + " is GOOD!");                }            } catch (Exception e) {                log.warn("Execution of ping query '" + poolPingQuery + "' failed: " + e.getMessage());                try {                    conn.getRealConnection().close();                } catch (Exception e2) {                    // ignore                }                result = false;                  if (log.isDebugEnabled()) {                    log.debug("Connection " + conn.getRealHashCode() + " is BAD: " + e.getMessage());                }            }        }        return result;    }
       复制代码
 
首先检测是否关闭了连接,如果关闭返回 false
如果没有关闭连接,并且配置中开启了 ping 连接池的功能,而且连接超过一定时长未使用,这时候通过执行 poolPingQuery 定义的 sql 来检测连接是否可用,如果没有异常就返回 true,否则返回 false
总结
这篇文章主要介绍了聊聊 Mybatis 的数据源 PooledDataSource 类一些方法,包括获取数据库连接的方法 getConnection(),方法中调用了 popConnection(),逻辑是先从空闲连接集合中获取连接信息,如果空闲集合中没有并活跃的连接数没有达到上限的时候就可以创建新的数据库连接,如果达到上限了就判断是否有超时的连接,如果有的话就利用这个超时连接创建新的连接并把超级连接设置为无效,如果超时连接也没有,这时候就调用 wait 方法进行阻塞,然后分析了一下 isValid()方法,这个方法是检测数据库连接是否可用,逻辑是通过执行 sql 语句来判断的。
评论