首页 > 代码库 > mybatis3中自带的连接池的问题

mybatis3中自带的连接池的问题

想在新项目中使用mybatis,于是这几天在看官方问题。

发现mytatis3中自带的连接池,不知道性能如何?

配置了连接池,为了验证连接池返回的连接是否是同一个连接

把poolMaximumActiveConnections这个属性配置为1,那么连接池中最多只有一个活跃连接了

然后用以下代码验证:

while (true) {
	Scanner sc = new Scanner(System.in);
	String str = sc.nextLine();
	if (str.equals("bye")) {
		break;
	}
	SqlSession session = sqlSessionFactory.openSession();
	System.out.println(System.identityHashCode(session.getConnection()));
	session.close();
}
但是方法,每次输出的值都不一样。疑惑。。。

于是跟踪源代码,发现

通过session.getConnection()这个方法返回的connection对象其实并不是原始的connection

而是个代理对象proxyConnection,它动态代理了那个原始Connection对象realConnection,为的是拦截realConnection的close方法

因为连接池中的连接并不应该去关闭,当调用close方法的时候应该是将此连接放回连接池的空闲队列中。

源码如下:

  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    String methodName = method.getName();
    if (CLOSE.hashCode() == methodName.hashCode() && CLOSE.equals(methodName)) {
      dataSource.pushConnection(this);
      return null;
    } else {
      try {
        if (!Object.class.equals(method.getDeclaringClass())) {
          // issue #579 toString() should never fail
          // throw an SQLException instead of a Runtime
          checkConnection();
        }
        return method.invoke(realConnection, args);
      } catch (Throwable t) {
        throw ExceptionUtil.unwrapThrowable(t);
      }
    }
  }

之后通过调试发现realConnection每次都是同一个,终于验证了想法!


另外:我发现PooledDataSource,也就是使用连接池的数据源其实内部持有了一个UnpooledDataSource的对象

基础的数据源操作(getConnection)和属性(username, password, url........)都在UnpooledDataSource中定义了

PooledDataSource只负责自己那块连接池的逻辑,其余的都交给UnpooledDataSource来处理